题目链接
参考了大佬博客思路摘抄如下:
数学题。我们观察变化。
00 -> 1010 出现 10、01
01 -> 1001 出现 10、00、01
10 -> 0110 出现 01、11、10
11 -> 0101 出现 01、10
只有01下一步会生成00,但是00、01、10、11都会生成01,每一个1都会生成01,而00也可以生成01,
由此分成两种情况计算;设O(n)是变化n步后1的个数,Z(n)是变化n步后生成的00的个数,有结论:
Z(n)= Z(n-2)+ O(n-2),O(n)= 2^(n-1){无论0、1都会生成0与1,所以是位数的一半}
#include<cstdio>
#include<cstring>
const int N=1e3+10;
int a[N][150],b[N][150];
void Init()
{
a[0][0]=a[1][0]=1;
memset(b,0,sizeof(b));
for(int i=2;i<=1000;i++)
for(int j=0;j<=140;j++)
{
a[i][j]+=a[i-1][j]*2;//n步后长度为2^n,一个数为2^(n-1)
b[i][j]+=b[i-2][j]+a[i-2][j];
a[i][j+1]+=a[i][j]/10000;//每位存四位数
a[i][j]%=10000;
b[i][j+1]+=b[i][j]/10000;
b[i][j]%=10000;
}
}
int main()
{
Init();
int n;
while(~scanf("%d",&n))
{
int i;
for(i=140;i&&!b[n][i];i--);
printf("%d",b[n][i--]);
for(;i>=0;i--)printf("%04d",b[n][i]);
puts("");
}
return 0;
}