题目大意
有两种地砖,每种无限个。用它们将 2*N 的地板填满,求方案数的后四位。
解题思路
搜索代码不难打出。
#include <cstdio>
int n;
int ans;
/*现在在now列,状态是stat
0: 00 1: 10 2: 00 3: 11 44: 00
00 00 10 00 11
*/
void dfs (int now, int stat){
// printf ("dfs %d %d\n", now, stat);
if (now>=n+1){
if (now==n+1&&!stat) ++ans;
return;
}
switch (stat){
case 0:
dfs (now+1, 0);
dfs (now+1, 1);
dfs (now+1, 2);
dfs (now, 3);
break;
case 1:
dfs (now+1, 2);
dfs (now+2, 0);
break;
case 2:
dfs (now+1, 1);
dfs (now+2, 0);
break;
case 3:
dfs (now+2, 0);
break;
case 4:
dfs (now+2, 0);
break;
default:
break;
}
}
int main(){
int T;
scanf ("%d", &T);
for (int i=1; i<=T; ++i){
ans=0; n=i;
dfs (1, 0);
printf ("%d %d\n", i, ans);
}
}
将前 10 项列出后不难发现规律。
#include <cstdio>
#include <cstdlib>
#include <cstring>
const int MAXN=1000010;
int n;
int f[MAXN+10];
int main(){
memset (f, 0, sizeof (f)); f[1]=1; f[2]=2; f[3]=5;
scanf ("%d", &n);
for (int i=4; i<=n; ++i)
f[i]=(f[i-1]*2+f[i-3])%10000;
printf ("%d", f[n]);
}
当然,动态规划也可。用类似搜索的方法记录状态,但是常数更大。