URAL1586——DP——Threeprime Numbers

Description

Rest at the sea is wonderful! However, programmer Pasha became awfully bored of lying on a beach in Turkey; so bored that he decided to count the quantity of three-digit prime numbers. This turned out to be so interesting that he then started to study threeprime numbers. Pasha calls an integer a threeprime number if any three consecutive digits of this integer form a three-digit prime number. Pasha had already started working on the theory of the divine origin of such numbers when some vandals poured water on Pasha and cried some incomprehensible words like “Sonnenstich!”, “Colpo di sole!”, and “Coup de soleil!”

You are to continue Pasha’s work and find out how often (or rare) threeprime numbers are.

Input

The input contains an integer n (3 ≤ n ≤ 10000).

Output

Output the quantity of n-digit threeprime numbers calculated modulo 10 9 + 9.

Sample Input

input output
4
204

大意:给你一个n表示几位数,让你输出满足三素数的数有多少个,三素数的定义为每三个连续的数都是一个素数

自己想到了大致要定义一个prime[j][k][l]来判断,还是想不出状态转移方程

状态转移方程  下一个状态可以由dp[i-1][k][l] 得到,所要添加的只是最高位,只要满足最高位以及接下来的两个数的集合也满足的话就行

也就是   dp[i][j][k] = dp[i][j][k] + dp[i-1][k][l],前一个状态的dp值是i-1位的时候所有满足条件的情况所以只要判prime[j][k][l]是素数就行

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
long long  dp[10100][10][10];
int prime[10][10][10];
const int mod = 1e9 + 9;
void solve()
{
    int j;
    memset(prime,0,sizeof(prime));
    for(int i = 100; i <= 999;i++){
        for( j = 2; j < i;j++){
            if(i%j == 0)
            break;
        }
        if(j >= i){
            int x1 = i/100;
            int x2 = (i%100)/10;
            int x3 = i%10;
            prime[x1][x2][x3] = 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-1][k][l] + dp[i][j][k]) % mod;

                }
            }
        }
    }
}
int main()
{
    solve();
    int n;
    while(~scanf("%d",&n)){
        long long  res = 0;
        for(int i = 1; i <= 9;i++){
            for(int j = 0 ; j <= 9;j++){
            res += 1ll*dp[n][i][j];
            res%=mod;
            }
        }
        printf("%lld\n",res);
    }
    return 0;
}

  

时间: 2024-08-05 14:48:55

URAL1586——DP——Threeprime Numbers的相关文章

递推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/detai

ural Threeprime Numbers(dp)

http://acm.timus.ru/problem.aspx?space=1&num=1586 题意没看懂,看了别人的翻译.threeprime number的意思是任意三个连续的数组成的一个三位数是素数,注意必须是三位数.给出n,问满足条件的n位数有多少个. 先把三位数的素数筛选出来并标记,设dp[i][j][k]表示到i位为止,最后两位是j和k的满足条件的数的个数. 那么dp[i][j][k] += dp[i-1][g][j]. #include <stdio.h> #incl

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&

URAL1009——DP——K-based Numbers

Description Let’s consider K-based numbers, containing exactly N digits. We define a number to be valid if its K-based notation doesn’t contain two successive zeros. For example: 1010230 is a valid 7-digit number; 1000198 is not a valid number; 00012

Codeforces 486D Valid Sets:Tree dp【n遍O(n)的dp】

题目链接:http://codeforces.com/problemset/problem/486/D 题意: 给你一棵树,n个节点,每个节点的点权为a[i]. 问你有多少个连通子图,使得子图中的max(a[i]) - min(a[i]) <= d. ps.连通子图的定义: 如果一个点集V为一个连通子图,则对于任意两点a,b∈V,有a到b路径上的所有点u∈V. 题解: 因为要保证max(a[i]) - min(a[i]) <= d,所以可以人为地选出一个点rt作为点权最大的点. 这样在求以rt

微软2016校招笔试 第一场部分题目个人思路

嗯--第一场当时还不知道报名,第二场报上了,拿了250/400,果然分如其人-- 这里包括的是第一场的ABC题,第二场的AB题的题解在另一篇(这些都是自己AC了的),第一场的D和第二场的C至今仍然在WA,不知道怎么回事,到时候也讲讲思路求指点吧. A. Magic Box 这道题并不难做,唯一需要注意的是cx,cy和cz,以及任意两个量的差之间是没有前后关系的(这个事情样例里也告诉你了),所以比较简单的方法就是先把cx,cy,cz排序,然后根据输入串一个一个模拟,然后计算出两两之间的差,排序,比

SPOJ BALNUM Balanced Numbers(数位dp,状态压缩)

BALNUM - Balanced Numbers no tags 题目链接 Balanced numbers have been used by mathematicians for centuries. A positive integer is considered a balanced number if: 1)      Every even digit appears an odd number of times in its decimal representation 2)   

Codeforces Beta Round #51---D. Beautiful numbers(数位dp, 巧妙)

Volodya is an odd boy and his taste is strange as well. It seems to him that a positive integer number is beautiful if and only if it is divisible by each of its nonzero digits. We will not argue with this and just count the quantity of beautiful num