Description–
小G最近发现了一种非常有趣的数,他将这种数称之为Sam数。Sam数具有以下特征:相邻两位的数字之差不超过2。小G还将Sam数按位数进行了分类,他将一个k位Sam数称之为k阶Sam数。但不幸的是小G发现他数不清第k阶的Sam数一共有多少个,这个时候机智的他想到了向你求助。
Input–
第一行为一个整数k,含义见题面。
Output–
一行一个整数ans,表示k阶的Sam数的个数。
由于第k阶Sam数非常多,你只需要输出ans mod 1,000,000,007。
Sample Input–
4
Sample Output–
867
说明–
数据规模
对于30%的数据,1 ≤ k ≤ 6。
对于60%的数据,1 ≤ k ≤ 1000。
对于100%的数据,1 ≤ k ≤ 1000000。
解题思路–
看了一下数据,发现好像不能直接判断sim数,那就得制造了(不情愿。。。 )
第一位(从左到右)可以是1~9
根据题意,
0的后面可接0,1,2;
1的后面可接0,1,2,3;
2的后面可接0,1,2,3,4;
3的后面可接1,2,3,4,5;
4的后面可接2,3,4,5,6;
5的后面可接3,4,5,6,7;
6的后面可接4,5,6,7,8;
7的后面可接5,6,7,8,9;
8的后面可接6,7,8,9;
9的后面可接7,8,9.
如此反复。。。。。。
有0,无01,02,001,002,0001,0002······
代码–
#include<cstdio>
#include<algorithm>
using namespace std;
int z[10]={3,4,5,5,5,5,5,5,4,3};
const long long N=1000000007;
long long s,ans=10,a[3][15];
long long l,k,t;
void hhh(int t)
{
a[1][0]=a[2][0];a[1][1]=a[2][1];a[1][2]=a[2][2];a[1][3]=a[2][3];
a[1][4]=a[2][4];a[1][5]=a[2][5];a[1][6]=a[2][6];a[1][7]=a[2][7];
a[1][8]=a[2][8];a[1][9]=a[2][9];a[2][0]=0;a[2][1]=0;a[2][2]=0;
a[2][3]=0;a[2][4]=0;a[2][5]=0;a[2][6]=0;a[2][7]=0;a[2][8]=0;a[2][9]=0;//手动---
if (t==2) l=1;
else l=0;
for (int i=l;i<=9;++i)
{
if (i>1)
a[2][i-2]=(a[2][i-2]+a[1][i])%N;
if (i>0)
a[2][i-1]=(a[2][i-1]+a[1][i])%N;
a[2][i]=(a[2][i]+a[1][i])%N;
a[2][i+1]=(a[2][i+1]+a[1][i])%N;a[2][i+2]=(a[2][i+2]+a[1][i])%N;//制造中······
}
}
int main()
{
scanf("%d",&k);
a[2][1]=1;a[2][2]=1;a[2][3]=1;a[2][4]=1;
a[2][5]=1;a[2][6]=1;a[2][7]=1;a[2][8]=1;a[2][9]=1;//手动---
for (int i=2;i<=k;++i)
hhh(i);
if (k>1)
{
ans=0;
for (int i=0;i<=9;++i)
ans=(ans+a[1][i]*z[i])%N;
}
printf("%lld",ans);
return 0;
}