Timus 1586
想一想知道n-1位的结果,如何得到n位的结果呢?假如我们知道n-1的后两位再枚举第n位的数字,不就得到n位的结果了吗?
我们用res[n][i][j]表示n位最后两位是i和j;
Res[i][j][k]=∑res[i-1][l][j];(其中100*l+10*j+k 是素数)
我们还可以优化一下,因为最后一位只有可能是1、3、7、9。所以可以将k和j所在的循环的长度改为4。
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> using namespace std; int res[10001][10][10],flag[1000],b[4]={1,3,7,9}; int IsPrime(int w) { int i,k; k=sqrt(w*1.0); for(i=2;i<=k;i++) if(w%i==0) return 0; return 1; } int main() { int i,j,k,n,w,l,sum; for(i=1;i<10;i++) for(j=0;j<10;j++) for(k=0;k<4;k++) { w=i*100+j*10+b[k]; if(IsPrime(w)) { flag[w]=1; res[3][j][b[k]]++; } } for(i=1;i<10001;i++) for(j=0;j<4;j++) for(k=0;k<4;k++) for(l=0;l<10;l++) if(flag[100*l+10*b[j]+b[k]]) { res[i][b[j]][b[k]]+=res[i-1][l][b[j]]; res[i][b[j]][b[k]]%=1000000009; } sum=0; while(scanf("%d",&n)!=EOF) { for(i=0;i<10;i++) for(j=0;j<10;j++) { sum+=res[n][i][j]; sum%=1000000009; } printf("%d\n",sum); } return 0; }