zoukankan      html  css  js  c++  java
  • 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
    ",cse,res);
        }
        return 0;
    }
    
  • 相关阅读:
    迭代器
    逻辑量词
    How to distinguish between strings in heap or literals?
    Is the “*apply” family really not vectorized?
    power of the test
    The Most Simple Introduction to Hypothesis Testing
    析构函数允许重载吗?
    C++中析构函数的作用
    在C#中的构造函数和解析函数
    c++构造函数与析构函数
  • 原文地址:https://www.cnblogs.com/WABoss/p/6009178.html
Copyright © 2011-2022 走看看