思路
首先读题可得设 f [ i ] f[i] f[i] 表示 2 ∗ i 2*i 2∗i 时的方案数。
因为边最长是2,所以考虑从 f [ i − 1 ] f[i-1] f[i−1] 和 f [ i − 2 ] f[i-2] f[i−2] 转移。
i − 2 i-2 i−2 时的情况:
i − 1 i-1 i−1 时只有可能有一条竖着的,所以直接继承 f [ i − 1 ] f[i-1] f[i−1]。
当然此时存在了重复, i − 2 i-2 i−2 的两条竖着的情况和 i − 1 i-1 i−1 的情况发生了冲突,
所以直接把 i − 2 i-2 i−2 的情况剔除即可。
需要高精度。
C o d e Code Code
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
long long f[300][101];
int n,m;
void gjc(int x)
{
int jw=0;
for(int i=1; i<=f[x-2][0]+1; i++)
{
f[x][i]=(f[x-2][i]*2)%10+jw;
jw=(f[x-2][i]*2)/10;
}
if(f[x][f[x-2][0]+1]!=0)
f[x][0]=f[x-2][0]+1;
else
f[x][0]=f[x-2][0];
}
void gjj(int x)
{
int jw=0;
for(int i=1; i<=f[x][0]+1; i++)
{
int g=(f[x][i]+f[x-1][i]+jw);
f[x][i]=g%10;
jw=g/10;
}
if(f[x][f[x][0]+1]!=0)
f[x][0]=f[x-1][0]+1;
}
int main()
{
f[1][1]=1,f[2][1]=3,f[1][0]=1,f[2][0]=1;
for(int i=3; i<=250; i++)
{
gjc(i);
gjj(i);
}
//f[i]=f[i-2]*2+f[i-1];
while(cin>>n)
{
int i=f[n][0];
while(f[n][i]==0)
i--;
for(int i=f[n][0]; i>=1; i--)
cout<<f[n][i];
cout<<endl;
}
return 0;
}