URAL 1586 Threeprime Numbers (数位DP)
博客原文地址:http://blog.csdn.net/xuechelingxiao/article/details/38658153
题目大意:首先定义一个Threeprime Numbers, Threeprime Numbers的含义就是:对于一个数,这个数中任意连续的三个数字组成的三位数都是素数,那么这个数就是Threeprime Numbers,求1到n中所有Threeprime Numbers的数量。
解题思路:数位DP。 dp[i][j][k], i表示当前枚举的数是个几位数,j表示当前数的最高位,k表示次高位。对于当前的i位数,在他前面加上一个数字,如果使得加上的数字与最高位跟次高位组成的三位数是个素数,那么即可推到下一个状态。也就是说,当前的dp[i][加上的数字][j]是由dp[i-1][j][k]推过来的。枚举加上的数字就可以,当然加上的数字不能为0。
1 #include <stdio.h> 2 const int MOD = 1e9+9; 3 #define maxn 1000 4 int prime[maxn/3]; 5 bool flag[maxn]; 6 void get_prime() 7 { 8 int k = 0; 9 for(int i = 2; i < maxn; i++){ 10 if(!flag[i]) 11 prime[k++] = i; 12 for(int j = 0; j < k && i*prime[j] < maxn; j++){ 13 flag[i*prime[j]] = true; 14 if(i%prime[j] == 0) break; 15 } 16 } 17 } 18 19 int n; 20 int dp[10005][11][11]; 21 22 int main() 23 { 24 get_prime(); 25 int cnt = 0; 26 for(int i = 100; i < 1000; ++i){ 27 if(flag[i] == 0){ 28 cnt++; 29 } 30 } 31 //printf("%d\n", cnt); 32 scanf("%d", &n); 33 for(int i = 100; i < 1000; ++i){ 34 if(flag[i] == 0){ 35 dp[3][i/100][i%100/10]++; 36 } 37 } 38 39 for(int i = 4; i <= n; ++i){ 40 for(int j = 1; j <= 9; ++j){ 41 for(int k = 0; k < 10; ++k){ 42 for(int l = 0; l < 10; ++l){ 43 if(flag[j*100+k*10+l] == 0){ 44 dp[i][j][k] += dp[i-1][k][l]; 45 dp[i][j][k] %= MOD; 46 } 47 } 48 } 49 } 50 } 51 52 int sum = 0; 53 for(int i = 0; i < 10; ++i){ 54 for(int j = 0; j < 10; ++j){ 55 sum += dp[n][i][j]; 56 sum %= MOD; 57 //printf("%d\n", dp[n][i][j]); 58 } 59 } 60 printf("%d\n", sum); 61 62 return 0; 63 }