——Kurisu、红

# HDU 5456 Matches Puzzle Game [数位DP]

Problem Description
As an exciting puzzle game for kids and girlfriends, the Matches Puzzle Game asks the player to find the number of possible equations AB=C with exactly n (5n500) matches (or sticks).

In these equations, A,B and C are positive integers. The equality sign needs two matches and the sign of subtraction needs just one. Leading zeros are not allowed.

Input
The input contains several test cases. The first line of the input is a single integer t which is the number of test cases. Then t (1t30) test cases follow.

Each test case contains one line with two integers n (5n500)         m (3m2×109).

Output
For each test case, you should output the answer modulo m.

(状态比较丑，A,B的状态其实可以只表示成2种：0：没到最高位，1：已经到过最高位)

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<iostream>
#include<stdlib.h>
#include<set>
#include<map>
#include<queue>
#include<vector>
#include<bitset>
template <class T>
bool scanff(T &ret){ //Faster Input
char c; int sgn; T bit=0.1;
if(c=getchar(),c==EOF) return 0;
while(c!='-'&&c!='.'&&(c<'0'||c>'9')) c=getchar();
sgn=(c=='-')?-1:1;
ret=(c=='-')?0:(c-'0');
while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
if(c==' '||c=='\n'){ ret*=sgn; return 1; }
while(c=getchar(),c>='0'&&c<='9') ret+=(c-'0')*bit,bit/=10;
ret*=sgn;
return 1;
}
#define inf 1073741823
#define llinf 4611686018427387903LL
#define PI acos(-1.0)
#define lth (th<<1)
#define rth (th<<1|1)
#define rep(i,a,b) for(int i=int(a);i<=int(b);i++)
#define drep(i,a,b) for(int i=int(a);i>=int(b);i--)
#define gson(i,root) for(int i=ptx[root];~i;i=ed[i].next)
#define tdata int testnum;scanff(testnum);for(int cas=1;cas<=testnum;cas++)
#define mem(x,val) memset(x,val,sizeof(x))
#define mkp(a,b) make_pair(a,b)
#define findx(x) lower_bound(b+1,b+1+bn,x)-b
#define pb(x) push_back(x)
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
#define NN 2200000

unsigned int dp[501][2][3][3];
//棒数 进位 A的状态，B的状态 ：状态0表示前导为1-9，1表示前导为0,2表示前导为空格

int mod,n;
int cot[11]={6,2,5,5,4,5,6,3,7,6,0};

int main(){
tdata{
mem(dp,0);
scanff(n);scanff(mod);
n-=3;
rep(a,0,9)
rep(b,0,9){
int c=a+b,k=0,as=0,bs=0;
if(c>=10){
c-=10;
k=1;
}
if(a==0)as=1;
if(b==0)bs=1;
int tot=cot[a]+cot[b]+cot[c];
dp[tot][k][as][bs]++;
dp[tot][k][as][bs]%=mod;
}
rep(i,0,n)
rep(k,0,1)
rep(as,0,2)
rep(bs,0,2){
if(as==2&&bs==2)continue;
if(dp[i][k][as][bs]==0)continue;
int start_a=0,start_b=0;
int c,nk,nas,nbs,tot;
if(as==2)start_a=10;
if(bs==2)start_b=10;
rep(a,start_a,10){
if(a==10&&as==1)continue;
if(a==0)nas=1;
else if(a==10)nas=2;
else nas=0;
rep(b,start_b,10){
if(b==10&&bs==1)continue;
if(b==10&&a!=10)c=a+k;
if(a==10&&b!=10)c=b+k;
if(a!=10&&b!=10)c=a+b+k;
if(a==10&&b==10)c=k;
nk=0;
if(c>=10){
c-=10;
nk=1;
}
if(a==10&&b==10&&k==0){
c=10;
nk=0;
}
if(b==0)nbs=1;
else if(b==10)nbs=2;
else nbs=0;
tot=cot[a]+cot[b]+cot[c];
if(i+tot<=n){
dp[i+tot][nk][nas][nbs]+=dp[i][k][as][bs];
dp[i+tot][nk][nas][nbs]%=mod;
}
}
}
}
printf("Case #%d: %u\n",cas,dp[n][0][2][2]);
}
return 0;
}


03-15 1079

09-23 583

09-20 816

09-29 978

10-06 361

08-08 1344

08-08 167

11-11 1519

09-25 273

05-26 22