首页 > 代码库 > HDU_5456_数位dp

HDU_5456_数位dp

http://acm.hdu.edu.cn/showproblem.php?pid=5456

 

转化成a=b+c,dp[i][a][b][c]表示剩余i木棒,a是否有进位,b是否首尾,c是否首位,注意每次都要memset。

 

#include<iostream>#include<cstring>#include<cstdio>#define LL long longusing namespace std;int n,m,stick[10] = {6,2,5,5,4,5,6,3,7,6};LL dp[505][2][2][2];LL dfs(int sum,int a,int b,int c){    if(sum < 0) return 0;    if(dp[sum][a][b][c] != -1)  return dp[sum][a][b][c];    if(b && c)    {        if(!a && sum == 0)  return 1;        if(a && sum == stick[1])    return 1;    }    if(sum == 0)    return 0;    LL& temp = dp[sum][a][b][c];    temp = 0;    if(b == 0 && c == 0)    {        for(int i = 0;i <= 9;i++)        {            for(int j = 0;j <= 9;j++)            {                int sub = stick[i]+stick[j]+stick[(i+j+a)%10];                temp += dfs(sum-sub,(i+j+a)/10,0,0);                if(i != 0)  temp += dfs(sum-sub,(i+j+a)/10,1,0);                if(j != 0)  temp += dfs(sum-sub,(i+j+a)/10,0,1);                if(i != 0 && j != 0)    temp += dfs(sum-sub,(i+j+a)/10,1,1);                temp %= m;            }        }    }    else if(b == 0)    {        for(int i = 0;i <= 9;i++)        {            int sub = stick[i]+stick[(i+a)%10];            temp += dfs(sum-sub,(i+a)/10,0,1);            if(i != 0)  temp += dfs(sum-sub,(i+a)/10,1,1);            temp %= m;        }    }    else if(c == 0)    {        for(int i = 0;i <= 9;i++)        {            int sub = stick[i]+stick[(i+a)%10];            temp += dfs(sum-sub,(i+a)/10,1,0);            if(i != 0)  temp += dfs(sum-sub,(i+a)/10,1,1);            temp %= m;        }    }    temp %= m;    return temp;}int main(){    int T;    scanf("%d",&T);    for(int i = 1;i <= T;i++)    {        memset(dp,-1,sizeof(dp));        scanf("%d%d",&n,&m);        printf("Case #%d: %lld\n",i,dfs(n-3,0,0,0));    }    return 0;}

 

HDU_5456_数位dp