矩形覆盖:最直观的想法是,经典斐波拉契数列变形,递推公式为f(n)=f(n-1)+f(n-2)。接下来分别使用四种方法实现:递归、记忆化搜索、动态规划、滚动数组。其整体思路为:1个2*1的小矩形覆盖一个2*1的大矩形有一种方法,2个2*1的小矩形覆盖一个2*2的大矩形有两种方法,n个2*1的小矩形覆盖一个2*n的大矩形可以是:第一个小矩形竖着,那么其他的有n-1个;第一个小矩形横着,那么必定第二个也需要横着,那么其他的有n-2个。
int rectCover(int number) {
if(number==0)
return 0;
// 1个2*1的小矩形覆盖一个2*1的大矩形有一种方法
if(number==1)
return 1;
// 2个2*1的小矩形覆盖一个2*2的大矩形有两种方法
if(number==2)
return 2;
// n个2*1的小矩形覆盖一个2*n的大矩形可以是:第一个小矩形竖着,那么其他的有n-1个;第一个小矩形横着,那么必定第二个也需要横着,那么其他的有n-2个
return rectCover(number-1)+rectCover(number-2);
}
// 0<=n<=38
int memo[40]={0};
int rectCover(int number) {
if(number==0)
return 0;
// 1个2*1的小矩形覆盖一个2*1的大矩形有一种方法
if(number==1)
return 1;
// 2个2*1的小矩形覆盖一个2*2的大矩形有两种方法
if(number==2)
return 2;
if(memo[number]!=0)
return memo[number];
// n个2*1的小矩形覆盖一个2*n的大矩形可以是:第一个小矩形竖着,那么其他的有n-1个;第一个小矩形横着,那么必定第二个也需要横着,那么其他的有n-2个
return memo[number]=rectCover(number-1)+rectCover(number-2);
}
int rectCover(int number) {
vector<int> dp(number+1,0);
dp[0]=0;
// 1个2*1的小矩形覆盖一个2*1的大矩形有一种方法
dp[1]=1;
// 2个2*1的小矩形覆盖一个2*2的大矩形有两种方法
dp[2]=2;
for(int i=3;i<=number;i++)
// n个2*1的小矩形覆盖一个2*n的大矩形可以是:第一个小矩形竖着,那么其他的有n-1个;第一个小矩形横着,那么必定第二个也需要横着,那么其他的有n-2个
dp[i]=dp[i-1]+dp[i-2];
return dp[number];
}
int rectCover(int number) {
if(number==0)
return 0;
if(number==1)
return 1;
if(number==2)
return 2;
// 1个2*1的小矩形覆盖一个2*1的大矩形有一种方法
int a=1;
// 2个2*1的小矩形覆盖一个2*2的大矩形有两种方法
int b=2;
int c;
for(int i=3;i<=number;i++)
{
// n个2*1的小矩形覆盖一个2*n的大矩形可以是:第一个小矩形竖着,那么其他的有n-1个;第一个小矩形横着,那么必定第二个也需要横着,那么其他的有n-2个
c=a+b;
a=b;
b=c;
}
return c;
}



京公网安备 11010502036488号