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 long using 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; }