递推DP URAL 1586 Threeprime Numbers

 

题目传送门

 1 /*
 2     题意:n位数字,任意连续的三位数字组成的数字是素数,这样的n位数有多少个
 3     最优子结构:考虑3位数的数字,可以枚举出来,第4位是和第3位,第2位组成的数字判断是否是素数
 4                 所以,dp[i][j][k] 表示i位数字,最高位数字j,第二高位数字k
 5                 状态转移方程:dp[i][j][k] += dp[i-1][k][l]
 6                 注意:最高位从1开始枚举:)
 7     详细解释:http://blog.csdn.net/zhangyanxing666/article/details/9628563
 8 */
 9 #include <cstdio>
10 #include <iostream>
11 #include <algorithm>
12 #include <cstring>
13 #include <cmath>
14 using namespace std;
15 
16 const int MAXN = 1e4 + 10;
17 const int INF = 0x3f3f3f3f;
18 const int MOD = 1e9 + 9;
19 int prime[11][11][11];
20 int vis[1010];
21 int dp[MAXN][11][11];
22 
23 void solve(void)
24 {
25     memset (prime, 0, sizeof (prime));
26     memset (vis, 0, sizeof (vis));
27     memset (dp, 0, sizeof (dp));
28     for (int i=2; i<=1000; ++i)
29     {
30         if (!vis[i])
31         {
32             vis[i] = true;
33             for (int j=i*2; j<=1000; j+=i)
34             {
35                 vis[j] = true;
36             }
37             prime[i/100][i/10%10][i%10] = 1;
38         }
39     }
40 
41     for (int i=1; i<=9; ++i)
42     {
43         for (int j=0; j<=9; ++j)
44         {
45             for (int k=0; k<=9; ++k)    if (prime[i][j][k])    dp[3][i][j]++;
46         } 
47     }
48 
49     for (int i=4; i<=10000; ++i)
50     {
51         for (int j=1; j<=9; ++j)
52         {
53             for (int k=0; k<=9; ++k)
54             {
55                 for (int l=0; l<=9; ++l)
56                     if (prime[j][k][l])    dp[i][j][k] = (dp[i][j][k] + dp[i-1][k][l]) % MOD;
57             }
58         }
59     }
60 }
61 
62 int main(void)        //URAL 1586 Threeprime Numbers
63 {
64     //freopen ("M.in", "r", stdin);
65 
66     solve ();
67     int n;
68     while (scanf ("%d", &n) == 1)
69     {
70         int ans = 0;
71         for (int i=1; i<=9; ++i)
72         {
73             for (int j=0; j<=9; ++j)
74                 ans = (ans + dp[n][i][j]) % MOD;
75         }
76 
77         printf ("%d\n", ans);
78     }
79 
80     return 0;
81 }

 

转载于:https://www.cnblogs.com/Running-Time/p/4490516.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值