hdu5456(记忆化搜索)

来源:互联网 发布:ise12.3软件下载 编辑:程序博客网 时间:2024/06/05 02:52

题目链接:hdu5456


题目大意:用n根火柴正好摆出A-B=C,求一共有多少种方法。(n根火柴包括‘-’,‘=’,且A,B,C不能有前导0)


题目分析:具体见代码。参考资料:大神博客


代码:

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;typedef long long LL;const int maxn=1000;int n,T,mod,Case=1;int stick[10]={6, 2, 5, 5, 4, 5, 6, 3, 7, 6};/*    式子可以变换成A=B+C,从低位处理到高位,    dp[i][j][b][c]表示到第i位,j有没进位,    b为数字B是否已经到达最高位,c为数字C是否已经到达最高位。    ps:如果b为1,代表B的值已经确定*/LL dp[maxn][2][2][2];//rest:还剩下多少火柴棍 carry:B和C的对应位相加是否产生了进位//b:B是否确定 c:C是否确定LL dfs(int rest,int carry,int b,int c){    if(rest<0)  return 0;    LL& ans=dp[rest][carry][b][c];    if(ans!=-1) return ans; //记忆化    /*        B和C的值已经确定:1.火柴棒已经用完(且B和C的最高位相加未产生进位)                          2.火柴棒还剩下2根,这时可以在A的前面加一个1使式子成立(B和C的最高位相加产生进位)        这两种情况都是符合题意的情况    */    if(((rest==stick[1]&&carry==1)||(rest==0&&carry==0))&&b&&c) return ans=1;    ans=0;    if(b==0&&c==0){ //B和C都未确定        for(int i=0;i<10;i++){            for(int j=0;j<10;j++){                int high=(i+j+carry)/10,low=(i+j+carry)%10;                //B和C都没有确定                ans+=dfs(rest-stick[i]-stick[j]-stick[low],high,0,0);                //B确定                if(i)   ans+=dfs(rest-stick[i]-stick[j]-stick[low],high,1,0);                //C确定                if(j)   ans+=dfs(rest-stick[i]-stick[j]-stick[low],high,0,1);                //B和C确定                if(i&&j)    ans+=dfs(rest-stick[i]-stick[j]-stick[low],high,1,1);                ans=ans%mod;            }        }    } else if(b==0){    //B已经确定        for(int i=0;i<10;i++){            int high=(i+carry)/10,low=(i+carry)%10;            ans+=dfs(rest-stick[i]-stick[low],high,0,1);            if(i)   ans+=dfs(rest-stick[i]-stick[low],high,1,1);            ans=ans%mod;        }    } else if(c==0){    //C已经确定        for(int i=0;i<10;i++){            int high=(i+carry)/10,low=(i+carry)%10;            ans+=dfs(rest-stick[i]-stick[low],high,1,0);            if(i)   ans+=dfs(rest-stick[i]-stick[low],high,1,1);            ans=ans%mod;        }    }    return ans%mod;}int main(){//    freopen("in.txt","r",stdin);    for(scanf("%d",&T);T--;){        scanf("%d%d",&n,&mod);        memset(dp,-1,sizeof(dp));        printf("Case #%d: %lld\n",Case++,dfs(n-3,0,0,0));    }    return 0;}


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 小孩子头睡偏了怎么办 7岁儿童头睡偏了怎么办 婴儿后脑睡平了怎么办 六个月宝宝免疫力低怎么办 十个月宝宝食烧怎么办 6个月宝宝感冒了怎么办 5个月宝宝腿短怎么办 5个月宝宝太瘦怎么办 宝宝喝了浓奶粉怎么办 一岁把尿不尿怎么办 五个月的宝宝大便干燥怎么办 婴儿便秘怎么办什么方法最有效 8个月小孩便秘怎么办 1个月新生儿便秘怎么办 新生儿头竖立0分怎么办 20天的宝宝便秘怎么办 出生23天的宝宝便秘怎么办 喝奶粉的宝宝便秘怎么办 抱孩子抱的驼背怎么办 4岁宝宝不拉屎怎么办 小朋友大便拉不出来怎么办 儿童便秘拉不出来怎么办 没感冒喉咙有痰怎么办 宝宝喂不进去药怎么办 新生儿只放屁不拉大便怎么办 新生儿腹胀不拉大便怎么办 8月宝宝咳嗽有痰怎么办 2个月婴儿惊吓怎么办 吃了米粉不拉屎怎么办 奇异果奶昔苦了怎么办 8个月宝宝偏瘦怎么办 一岁宝宝螺旋腿怎么办 七个月宝宝晚上咳嗽厉害怎么办 孕7个月感冒咳嗽怎么办 4个月婴儿肺炎怎么办 宝宝吃胡萝卜泥拉肚子怎么办 宝宝吃土豆泥不消化怎么办 五个月宝宝奶睡怎么办 橘子和牛奶一起吃了怎么办 半岁宝宝不喝水怎么办 一岁宝宝总是便秘怎么办