您的位置:首页 > 其它

递推DP URAL 1586 Threeprime Numbers

2015-05-09 15:34 465 查看
题目传送门

 /*
题意:n位数字,任意连续的三位数字组成的数字是素数,这样的n位数有多少个
最优子结构:考虑3位数的数字,可以枚举出来,第4位是和第3位,第2位组成的数字判断是否是素数
所以,dp[i][j][k] 表示i位数字,最高位数字j,第二高位数字k
状态转移方程:dp[i][j][k] += dp[i-1][k][l]
注意:最高位从1开始枚举:)
详细解释:http://blog.csdn.net/zhangyanxing666/article/details/9628563
*/
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;

const int MAXN = 1e4 + 10;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 9;
int prime[11][11][11];
int vis[1010];
int dp[MAXN][11][11];

void solve(void)
{
memset (prime, 0, sizeof (prime));
memset (vis, 0, sizeof (vis));
memset (dp, 0, sizeof (dp));
for (int i=2; i<=1000; ++i)
{
if (!vis[i])
{
vis[i] = true;
for (int j=i*2; j<=1000; j+=i)
{
vis[j] = true;
}
prime[i/100][i/10%10][i%10] = 1;
}
}

for (int i=1; i<=9; ++i)
{
for (int j=0; j<=9; ++j)
{
for (int k=0; k<=9; ++k)    if (prime[i][j][k])    dp[3][i][j]++;
}
}

for (int i=4; i<=10000; ++i)
{
for (int j=1; j<=9; ++j)
{
for (int k=0; k<=9; ++k)
{
for (int l=0; l<=9; ++l)
if (prime[j][k][l])    dp[i][j][k] = (dp[i][j][k] + dp[i-1][k][l]) % MOD;
}
}
}
}

int main(void)        //URAL 1586 Threeprime Numbers
{
//freopen ("M.in", "r", stdin);

solve ();
int n;
while (scanf ("%d", &n) == 1)
{
int ans = 0;
for (int i=1; i<=9; ++i)
{
for (int j=0; j<=9; ++j)
ans = (ans + dp
[i][j]) % MOD;
}

printf ("%d\n", ans);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: