问题
题目:[矩形覆盖]
思路
先说我自己想的思路,主要分两种情形:
1. 全部竖着放,这是一种。
2. 至少有一种横着放,那么当N是偶数的情形,n= N/2;此时,所有的情况是
C1n+C2n+...Cnn
,问题是奇数的情形,这种排列数我没想清楚,这个题最终还是栽在了数学上。还是,上来先想,锻炼思维是最重要的。
代码(未AC)
class Solution {
public:
int rectCover(int number) {
if(number < 1) return 0;
else if(1==number) return 1;
else{
int ans = 1;
if(0== number%2){
int max = number/2;
for(int i = 1; i <= max; ++i){
ans += C(max, i);
}
}
else{
// 奇数情形的组合数我没有想清楚
// ...
}
return ans;
}
}
private:
int C(int n, int k){
return 1.0/fact(n-k)*fact(n);
}
int fact(int n){
if(n < 0) return -1;
else if( 0==n || 1==n ) return 1;
else{
int ret = 1;
for(int i = 2; i <= n; ++i){
ret *= i;
}
return ret;
}
}
};
思路1
参照了这篇链接[ 剑指offer: 矩形覆盖(循环与递归)]
直接上图吧,比较情形。
(该图来自于上文链接,并非原创,特此说明)
假设N=3,
一开始有两种选择,要么横着放,要么竖着放。
这不和上楼梯一样,一次迈一步,或者一次迈两步。
所以,上图可以理解为从右向左迈步子的时候,最后一次,要么迈一步,要么迈两步。
那么有,
f(n)=f(n−1)+f(n−2)
代码1
class Solution {
public:
int rectCover(int number) {
if(number <= 0) return 0;
else if(1==number) return 1;
else if(2==number) return 2;
else{
long f1 = 1;
long f2 = 2;
for(int i = 3; i <= number; ++i){
long t = f1 + f2;
f1 = f2;
f2 = t;
}
return f2;
}
}
};