【劍指offer】10:矩形覆蓋
題目描述:
我們可以用2*1的小矩形橫著或者豎著去覆蓋更大的矩形。請問用n個2*1的小矩形無重疊地覆蓋一個2*n的大矩形,總共有多少種方法?
解題思路:
①方法一
對於這種題沒有思路怎麼辦?可以先從最簡單的情況開始考慮:
顯然,當n = 1時,只有一種方法
當n = 2時,如圖有兩種方法
當n = 3時,如圖有三種方法
當我們做到這裡總會出現錯覺,是不是n等於幾就是有幾種方法呢?我們再接著來嘗試:
當n = 4時,如圖有五種方法。
做到這裡基本上會確定就是斐波拉契數列了,可以接著驗證,這裡不做贅述
②方法二
可以先把2X4的覆蓋方法記為f(4)【如上圖n=4時的第一個圖】,用1X2的小矩形去覆蓋時,有兩種選擇:橫著放或者豎著放。當豎著放時,右邊還剩下2X3的區域。很明顯這種情況下覆蓋方法為f(3)。當橫著放時,1X2的矩形放在左上角,其下方區域只能也橫著放一個矩形,此時右邊區域值剩下2X2的區域,這種情況下覆蓋方法為f(2)。所以可以得到:f(4)=f(3)+f(2),不難看出這仍然是斐波那契數列。
特殊情況:f(1)=1,f(2)=2
程式碼實現
(C實現):
int rectCover(number) { // write code here int fir = 1, sec = 2, res; if (number <= 0 || number == 1 || number == 2) return number; for (int i = 2; i <number; i++) { res = fir + sec; fir = sec; sec = res; } //res = rectCover(number - 1) + rectCover(number - 2); 遞歸方式 return res; }
(JavaScript實現):
function rectCover(number) { // write code here var fir = 1, sec = 2, res; if (number <= 0 || number == 1 || number == 2) { return number; } for (var i = 2; i <number; i++) { res = fir + sec; fir = sec; sec = res; } //res = rectCover(number - 1) + rectCover(number - 2); 遞歸方式 return res; }