递推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 }
时间: 2024-10-18 11:34:46

递推DP URAL 1586 Threeprime Numbers的相关文章

递推DP URAL 1353 Milliard Vasya&#39;s Function

题目传送门 1 /* 2 题意:1~1e9的数字里,各个位数数字相加和为s的个数 3 递推DP:dp[i][j] 表示i位数字,当前数字和为j的个数 4 状态转移方程:dp[i][j] += dp[i-1][j-k],为了不出现负数 5 改为:dp[i][j+k] += dp[i-1][j] 6 */ 7 #include <cstdio> 8 #include <cstring> 9 #include <cmath> 10 #include <algorithm

递推DP URAL 1031 Railway Tickets

题目传送门 1 /* 2 简单递推DP:读题烦!在区间内的都更新一遍,dp[]初始化INF 3 注意:s1与s2大小不一定,坑! 4 详细解释:http://blog.csdn.net/kk303/article/details/6847948 5 */ 6 #include <cstdio> 7 #include <iostream> 8 #include <algorithm> 9 #include <cstring> 10 #include <s

递推DP URAL 1119 Metro

题目传送门 1 /* 2 题意:已知起点(1,1),终点(n,m):从一个点水平或垂直走到相邻的点距离+1,还有k个抄近道的对角线+sqrt (2.0): 3 递推DP:仿照JayYe,处理的很巧妙,学习:) 4 好像还要滚动数组,不会,以后再补 5 */ 6 #include <cstdio> 7 #include <iostream> 8 #include <algorithm> 9 #include <cmath> 10 #include <cs

递推DP URAL 1260 Nudnik Photographer

题目传送门 1 /* 2 递推DP: dp[i] 表示放i的方案数,最后累加前n-2的数字的方案数 3 */ 4 #include <cstdio> 5 #include <algorithm> 6 #include <cmath> 7 #include <cstring> 8 using namespace std; 9 10 const int MAXN = 1e4 + 10; 11 const int INF = 0x3f3f3f3f; 12 int

递推DP URAL 1017 Staircases

题目传送门 1 /* 2 题意:给n块砖头,问能组成多少个楼梯,楼梯至少两层,且每层至少一块砖头,层与层之间数目不能相等! 3 递推DP:dp[i][j] 表示总共i块砖头,最后一列的砖头数是j块的方案数 4 状态转移方程:dp[i][j] += dp[i-j][k] 表示最后一列是j,那么上一个状态是少了最后一列 5 总共i-j块砖头,倒数第二列是k块砖头.k<j, j<=i 6 最后累加dp[n][i], i<n因为最少要两层 7 dp[0][0] = 1; 8 还有更简单的做法,没

Ural 1586 Threeprime Numbers(DP)

题目地址:Ural 1586 先定义一个prime三维数组来记录素数,若i*100+j*10+k为素数,则标记prime[i][j][k]为1,否则为0.这样对后面的处理很方便. 然后定义一个dp三维数组,dp[n][i][j]表示当前n位的十位数字为i,个位数字为j时的素数个数,这时候状态要从prime[k][i][j]为素数时转移过来,所以状态转移方程为: if(prime[j][k][h])         dp[i][k][h]+=dp[i-1][j][k] 代码如下: #include

URAL 1586. Threeprime Numbers 数位dp

题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1586 题解:dp[i][j][k]表示长度为i,最高位为j,次高位为k的合法方案数,转移方程为当j*100+k*10+l为质数时dp[i][j][k]+=dp[i-1][k][l]; #include<bits/stdc++.h> #include<set> #include<iostream> #include<string> #include&

递推DP URAL 1081 Binary Lexicographic Sequence

题目传送门 1 /* 2 dp[i][1]/dp[i][0] 表示从左往右前i个,当前第i个放1或0的方案数 3 k -= dp[n][0] 表示当前放0的方案数不够了,所以必须放1,那么dp[n][0]个方案数都不能用了 4 相当于k减去这么多 5 详细解释:http://www.cnblogs.com/scau20110726/archive/2013/02/05/2892587.html 6 */ 7 #include <cstdio> 8 #include <algorithm&

递推DP URAL 1167 Bicolored Horses

题目传送门 1 /* 2 题意:k个马棚,n条马,黑马1, 白马0,每个马棚unhappy指数:黑马数*白马数,问最小的unhappy指数是多少 3 状态转移方程:dp[i][l] = min (dp[i][l], dp[i-1][j] + cur * (l - j - cur)) 表示第l匹马要不还在i马棚,或者去新的马棚 4 本题关键在dp初始化INF,由于黑马白马的表示简单,求指数方便 5 */ 6 #include <cstdio> 7 #include <iostream>