scauoj 18025 小明的密碼 數位DP

來源:互聯網
上載者:User

標籤:

18025 小明的密碼

時間限制:4000MS  記憶體限制:65535K
提交次數:0 通過次數:0

題型: 編程題   語言: G++;GCC

Description
小明的密碼由N(1<=N<=12)個數字構成,每個數字都可以是0至9中任意一個數字,但小明的密碼還有一個特點就是密碼中連續的M(1<=M<=4)個數位和是質數,現給定M和N,求滿足條件的密碼共有多少個?




輸入格式
第1行是T,case數量,此後T行,每行兩個數,N和M



輸出格式
每個case輸出一個滿足條件的密碼總數



輸入範例
21 12 1



輸出範例
416

 這題資料很小,可以直接DFS暴力求解,但是有更好的DP思路。。不過代碼略長dp[i][j][k][z],i表示當前是幾位元,j表示當前這個數的最後一位,k,z分別是倒數二、三位。
 假設M=4時.如果j+k+z+a是素數的時候,dp[i-1][k][z][a]可以推出dp[i][j][k][z],也就是dp[i][j][k][z]+=dp[i-1][k][z][a];
 這樣一來,我們就可以用暴力的方法求出dp[4][j][k][z],然後遞推上去。時間複雜度是n*10^m
 下面是代碼
#include <cstdio>#include <cstring>#include <cmath>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <set>#include <map>#include <stack>typedef long long ll;#define X first#define Y second#define mp(a,b) make_pair(a,b)#define pb push_back#define sd(x) scanf("%d",&(x))#define Pi acos(-1.0)#define sf(x) scanf("%lf",&(x))#define ss(x) scanf("%s",(x))#define maxn 1000000#include <ctime>  //如果是學校的同學要把這個刪掉,因為學校OJ禁了time標頭檔.const int inf=0x3f3f3f3f;const long long mod=1000000007;using namespace std;int dp[15][10][10][10];long long ans[15][5];bool prime[100];void get_prime(){    prime[0]=prime[1]=1;    for(int i=2;i<=40;i++)    {        if(!prime[i])        {            for(int j=i+i;j<=40;j+=i)                prime[j]=1;        }    }}void init(){    ans[0][1]=1;    //M=1    for(int i=1;i<=12;i++)        ans[i][1]=ans[i-1][1]*4;    //M=2    for(int i=0;i<=9;i++)        for(int j=0;j<=9;j++)            if(!prime[i+j])                dp[2][0][0][i]++;    for(int i=3;i<=12;i++)        for(int j=0;j<=9;j++)            for(int k=0;k<=9;k++)                if(!prime[j+k])                    dp[i][0][0][j]+=dp[i-1][0][0][k];    for(int i=1;i<=12;i++)        for(int j=0;j<=9;j++)            ans[i][2]+=dp[i][0][0][j];    //M=3    memset(dp,0,sizeof dp);    for(int i=0;i<=9;i++)        for(int j=0;j<=9;j++)            for(int k=0;k<=9;k++)                if(!prime[i+j+k])                    dp[3][0][i][j]++;    for(int i=4;i<=12;i++)        for(int j=0;j<=9;j++)            for(int k=0;k<=9;k++)                for(int z=0;z<=9;z++)                    if(!prime[j+k+z])                        dp[i][0][j][k]+=dp[i-1][0][k][z];    for(int i=1;i<=12;i++)        for(int j=0;j<=9;j++)            for(int k=0;k<=9;k++)                ans[i][3]+=dp[i][0][j][k];    //M=4    memset(dp,0,sizeof dp);    for(int i=0;i<=9;i++)        for(int j=0;j<=9;j++)            for(int k=0;k<=9;k++)                for(int z=0;z<=9;z++)                    if(!prime[i+j+k+z])                        dp[4][i][j][k]++;    for(int i=5;i<=12;i++)        for(int j=0;j<=9;j++)            for(int k=0;k<=9;k++)                for(int z=0;z<=9;z++)                    for(int a=0;a<=9;a++)                        if(!prime[j+k+z+a])                            dp[i][j][k][z]+=dp[i-1][k][z][a];    for(int i=1;i<=12;i++)        for(int j=0;j<=9;j++)            for(int k=0;k<=9;k++)                for(int a=0;a<=9;a++)                    ans[i][4]+=dp[i][j][k][a];}int main(){    #ifdef local    freopen("in","r",stdin);    //freopen("out","w",stdout);    int _time=clock();    #endif    get_prime();    init();    int T;    cin>>T;    while(T--)    {        int n,m;        cin>>n>>m;        cout<<ans[n][m]<<endl;    }    #ifdef local    printf("time: %d\n",int(clock()-_time));    #endif}
View Code

 

scauoj 18025 小明的密碼 數位DP

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.