Matches Puzzle Game
Matches Puzzle Game
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5456
数位DP
首先我把C-A=B改为A+B=C(我觉得会简单一点<( ̄3 ̄)>)
注意到前面填的数字不影响后面的数字,所以可以定义状态:
dp[i][j][a][b]表示已经用了i根火柴,进位为j,A前面能否再加数字(a),B前面能否再加数字(b)
然后根据a和b的值进行分类讨论即可。
(最近期中考好烦啊好多事都没弄)
代码如下:
1 /*苟利国家生死已,岂因祸福避趋之*/ 2 #include<cstdio> 3 #include<iostream> 4 #include<cstring> 5 #define MATCH 505 6 #define TOWARDS 2 7 #define FA 2//前止 8 #define FB 2 9 using namespace std; 10 typedef long long LL; 11 LL p[]={6,2,5,5,4,5,6,3,7,6}; 12 LL T,n,m,dp[MATCH][TOWARDS][FA][FB]; 13 void init(){ 14 memset(dp,0,sizeof(dp)); 15 dp[0][0][0][0]=1; 16 scanf("%I64d%I64d",&n,&m); 17 n-=3; 18 } 19 int main(void){ 20 scanf("%I64d",&T); 21 for(LL times=1;times<=T;++times){ 22 init(); 23 for(LL i=0;i<n;++i) 24 for(LL j=0;j<2;++j) 25 for(LL a=0;a<2;++a) 26 for(LL b=0;b<2;++b) 27 if(dp[i][j][a][b]){ 28 if(a==1&&b==1&&j==1&&i+p[1]<=n){ 29 dp[i+p[1]][0][1][1]=(dp[i+p[1]][0][1][1]+dp[i][j][a][b])%m; 30 }else if(a==1&&b==0){ 31 for(LL x=0;x<=9;++x){ 32 LL r=x+j; 33 LL rr=i+p[x]+p[r%10]; 34 if(rr<=n){ 35 dp[rr][r/10][a][0]=(dp[rr][r/10][a][0]+dp[i][j][a][b])%m; 36 if(x!=0)dp[rr][r/10][a][1]=(dp[rr][r/10][a][1]+dp[i][j][a][b])%m; 37 } 38 } 39 }else if(a==0&&b==1){ 40 for(LL x=0;x<=9;++x){ 41 LL r=x+j; 42 LL rr=i+p[x]+p[r%10]; 43 if(rr<=n){ 44 dp[rr][r/10][0][b]=(dp[rr][r/10][0][b]+dp[i][j][a][b])%m; 45 if(x!=0)dp[rr][r/10][1][b]=(dp[rr][r/10][1][b]+dp[i][j][a][b])%m; 46 } 47 } 48 }else if(a==0&&b==0){ 49 for(LL x=0;x<=9;++x) 50 for(LL y=0;y<=9;++y){ 51 LL r=x+y+j; 52 LL rr=i+p[x]+p[y]+p[r%10]; 53 if(rr<=n){ 54 dp[rr][r/10][a][b]=(dp[rr][r/10][a][b]+dp[i][j][a][b])%m; 55 if(x!=0)dp[rr][r/10][1][b]=(dp[rr][r/10][1][b]+dp[i][j][a][b])%m; 56 if(y!=0)dp[rr][r/10][a][1]=(dp[rr][r/10][a][1]+dp[i][j][a][b])%m; 57 if(x!=0&&y!=0)dp[rr][r/10][1][1]=(dp[rr][r/10][1][1]+dp[i][j][a][b])%m; 58 } 59 } 60 } 61 } 62 printf("Case #%I64d: %I64d\n",times,dp[n][0][1][1]); 63 } 64 }