HDU5456 Matches Puzzle Game(DP)

题目

Source

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

Description

As an exciting puzzle game for kids and girlfriends, the Matches Puzzle Game asks the player to find the number of possible equations A−B=C with exactly n (5≤n≤500) 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.

Please answer the number, modulo a given integer m (3≤m≤2×109).

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 (1≤t≤30) test cases follow.

Each test case contains one line with two integers n (5≤n≤500) and m (3≤m≤2×109).

Output

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

Sample Input

4
12 1000000007
17 1000000007
20 1000000007
147 1000000007

Sample Output

Case #1: 1
Case #2: 5
Case #3: 38
Case #4: 815630825

 

分析

题目求用N根火柴棒拼成A-B=C这种等式的方案数。

 

化成加法形式B+C=A,这样比较好写。
类似加法竖式的样子,从低位到高位,考虑DP:

  • dp[n][0/1][0/1][0/1]表示,还剩下的火柴棒数为n,是否向下一位进位,B最高位是否已确定,C最高位是否已确定

按字面意思转移。。

 

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
long long d[555][2][2][2];
int cost[10]={6,2,5,5,4,5,6,3,7,6};
int main(){
    int t,n;
    long long m;
    scanf("%d",&t);
    for(int cse=1; cse<=t; ++cse){
        scanf("%d%I64d",&n,&m);
        n-=3;
        memset(d,0,sizeof(d));
        d[n][0][0][0]=1;
        for(int len=n; len>0; --len){
            for(int i=0; i<=9; ++i){
                for(int j=0; j<=9; ++j){
                    if(cost[i]+cost[j]>len) continue;

                    int tmp0=len-cost[i]-cost[j]-cost[(i+j)%10];
                    int tmp1=len-cost[i]-cost[j]-cost[(i+j+1)%10];

                    if(tmp0>=0) d[tmp0][i+j>9][0][0]+=d[len][0][0][0],d[tmp0][i+j>9][0][0]%=m;
                    if(tmp1>=0) d[tmp1][i+j+1>9][0][0]+=d[len][1][0][0],d[tmp1][i+j+1>9][0][0]%=m;

                    if(i){
                        if(tmp0>=0) d[tmp0][i+j>9][1][0]+=d[len][0][0][0],d[tmp0][i+j>9][1][0]%=m;
                        if(tmp1>=0) d[tmp1][i+j+1>9][1][0]+=d[len][1][0][0],d[tmp1][i+j+1>9][1][0]%=m;
                    }
                    if(j){
                        if(tmp0>=0) d[tmp0][i+j>9][0][1]+=d[len][0][0][0],d[tmp0][i+j>9][0][1]%=m;
                        if(tmp1>=0) d[tmp1][i+j+1>9][0][1]+=d[len][1][0][0],d[tmp1][i+j+1>9][0][1]%=m;
                    }
                    if(i&&j){
                        if(tmp0>=0) d[tmp0][i+j>9][1][1]+=d[len][0][0][0],d[tmp0][i+j>9][1][1]%=m;
                        if(tmp1>=0) d[tmp1][i+j+1>9][1][1]+=d[len][1][0][0],d[tmp1][i+j+1>9][1][1]%=m;
                    }
                }
            }
            for(int i=0; i<=9; ++i){
                int tmp0=len-cost[i]-cost[i];
                int tmp1=len-cost[i]-cost[(i+1)%10];

                if(tmp0>=0) d[tmp0][0][0][1]+=d[len][0][0][1],d[tmp0][0][0][1]%=m;
                if(tmp1>=0) d[tmp1][i+1>9][0][1]+=d[len][1][0][1],d[tmp1][i+1>9][0][1]%=m;

                if(tmp0>=0) d[tmp0][0][1][0]+=d[len][0][1][0],d[tmp0][0][1][0]%=m;
                if(tmp1>=0) d[tmp1][i+1>9][1][0]+=d[len][1][1][0],d[tmp1][i+1>9][1][0]%=m;

                if(i){
                    if(tmp0>=0) d[tmp0][0][1][1]+=d[len][0][0][1],d[tmp0][0][1][1]%=m;
                    if(tmp1>=0) d[tmp1][i+1>9][1][1]+=d[len][1][0][1],d[tmp1][i+1>9][1][1]%=m;

                    if(tmp0>=0) d[tmp0][0][1][1]+=d[len][0][1][0],d[tmp0][0][1][1]%=m;
                    if(tmp1>=0) d[tmp1][i+1>9][1][1]+=d[len][1][1][0],d[tmp1][i+1>9][1][1]%=m;
                }
            }
        }
        long long res=(d[0][0][1][1]+d[cost[1]][1][1][1])%m;
        printf("Case #%d: %I64d\n",cse,res);
    }
    return 0;
}

 

posted @ 2016-10-28 19:41  WABoss  阅读(446)  评论(0编辑  收藏  举报