题目描述:
我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
思路:
2*1的情况只有一种
2*2的情况,当第一块横着放的时候第二块也必须横着放,当第一块竖着放的时候,会发现剩余部分又是2*1的情况
2*3的情况,当第一块横着放,剩余2*1,当第一块竖着放,剩余2*2的情况
因此,f[n] = f[n-1] + f[n-2]
#include <cstdio>
using namespace std;
int main()
{
long long f[100];
f[1] = f[0] = 1;
for(int i = 2; i <= 70; i++)
f[i] = f[i-1] + f[i-2];
int n;
while(scanf("%d", &n) != EOF){
printf("%lld\n", f[n]);
}
return 0;
}
写了发回溯,果断超时。。。
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 100;
int vis[2][maxn];
int n;
int ans;
void dfs(int x, int y){
if(x == 2){
ans++;
return;
}
if(vis[x][y]){
dfs(x, y + 1);
return;
}
if(y == n){
dfs(x + 1, 0);
return;
}
if(x == 0){//第一行
if(y != n-1 && !vis[x][y+1]){//横着放
vis[x][y] = vis[x][y+1] = 1;
dfs(x, y+1);
vis[x][y] = vis[x][y+1] = 0;
}
if(!vis[x+1][y]){//竖着放
vis[x][y] = vis[x+1][y] = 1;
dfs(x, y+1);
vis[x][y] = vis[x+1][y] = 0;
}
}
else{//第二行
if(y != n-1 && !vis[x][y+1]){//横着放
vis[x][y] = vis[x][y+1] = 1;
dfs(x, y+1);
vis[x][y] = vis[x][y+1] = 0;
}
}
}
void solve()
{
memset(vis, 0, sizeof(vis));
ans = 0;
dfs(0, 0);
printf("%d\n", ans);
}
int main()
{
while(scanf("%d", &n) != EOF)
solve();
return 0;
}