题目链接http://acm.hdu.edu.cn/showproblem.php?pid=4249

题目大意:给一个a+b=c的表达式,但是a、b、c中部分位的数字丢失,并用?代替,问有多少种方案使得这个表达式成立。

Sample Input
7+1?=1?
?1+?1=22
 
Sample Output
Case 1: 3
Case 2: 1
 
Hint

There are three solutions for the first case: 7+10=17, 7+11=18, 7+12=19 There is only one solution for the second case: 11+11=22 Note that 01+21=22 is not a valid solution because extra leading zeros are not allowed.

分析:网上的代码有2种,第一种:

  状态dp[len][i][j][k]表示三个数a,b,c的len位上的三个数字i , j, k 。

  if((i+j)%10==k)  //上一位不进1

  dp[len][i][j][k]+=dp[len-1][ii][jj][kk];其中ii+jj==kk||ii+jj+1==kk

  if((i+j+1)%10==k)  //上一位进1

  dp[len][i][j][k]+=dp[len-1][ii][jj][kk];

  其中ii+jj>=10&&(ii+jj)%10==kk,ii+jj+1>=0,(ii+jj+1)%10==kk

  最后答案是sum(dp[len-1][i][j][k]), (i+j==k||i+j+1==k)

代码如下:

 # include<iostream>
# include<cstring>
# include<cstdio>
# include<stack>
# include<algorithm>
# define LL __int64 //如果需要改成long long 的话多么方便
using namespace std; int len1,len2,len3,a[],b[],c[];
LL dp[][][][];
stack<char >st;
LL DP()
{
int i,j,k,l;
memset(dp,,sizeof(dp));
for(i=; i<; i++)
{
if(a[] != - && a[] != i) //枚举该位,如果不是?则必须是给定的数字i,不能枚举其他数
continue;
for(j=; j<; j++)
{
if(b[] != - && b[] != j)
continue;
for(k=; k<; k++)
{
if(c[] != - && c[] != k)
continue;
if((i+j)%==k)
dp[][i][j][k] = ;
}
}
}
for(l=; l<len3; l++) //从和的倒数第2位开始枚举
{
for(i=; i<; i++)
{
if(a[l] != - && a[l] != i)
continue;
if(l==len1- && i==) //首位不能是0
continue;
if(l>=len1 && i!=) //和比加数多余的位,相当于在加数的前面加0
continue;
for(j=; j<; j++)
{
if(b[l] !=- && b[l] !=j)
continue;
if(l==len2- && j==)
continue;
if(l>=len2 && j!=)
continue;
for(k=; k<; k++)
{
if(c[l] != - && c[l] !=k)
continue;
if(l==len3- && k==)
continue;
if((i+j)% !=k &&(i+j+)%!=k) //因为对应位上的三个数字a+b=c或者a+b+1=c;是从前往后进位的
continue;
if((i+j)%==k) //上一位不进1
{
for(int ii=; ii<; ii++)
for(int jj=; jj<; jj++)
for(int kk=; kk<; kk++)
{
if(dp[l-][ii][jj][kk] != &&(ii+jj==kk||ii+jj+==kk))
dp[l][i][j][k] += dp[l-][ii][jj][kk];
}
}
if((i+j+)%==k) //上一位进1
{
for(int ii=; ii<; ii++)ii+jj
for(int jj=; jj<; jj++)
for(int kk=; kk<; kk++)
{
if(dp[l-][ii][jj][kk] != &&(((ii+jj>= && (ii+jj)%==kk))||(ii+jj+>= &&(ii+jj+)%==kk)))
dp[l][i][j][k] += dp[l-][ii][jj][kk];
}
}
}
}
}
}
LL ans = ;
for(i=; i< ; i++)
for(j=; j<; j++)
for(k=; k<; k++)
{
if(dp[len3-][i][j][k] != && (i+j==k || i+j+==k))
ans += dp[len3-][i][j][k];
}
return ans;
}
int main()
{
char s[];
int cas=;
while(~scanf("%s",s))
{
int i,len = strlen(s);
memset(a,,sizeof(a));
memset(b,,sizeof(b));
memset(c,,sizeof(c));
for(i=; s[i]!='+'; i++)
st.push(s[i]);
len1 = ;
while(!st.empty()) //提取第一个加数,逆序存放到a数组里边,这样进位就是从前往后进位
{
if(st.top() != '?')
a[len1++] = st.top()-'';
else a[len1++] = -;
st.pop();
}
for(i++; s[i] != '='; i++)
st.push(s[i]);
len2 = ;
while(!st.empty()) //提取第2个加数
{
if(st.top() != '?')
b[len2++] = st.top() - '';
else b[len2++] = -;
st.pop();
}
for(i++; i<len; i++)
st.push(s[i]);
len3 = ;
while(!st.empty()) //提取第3个加数
{
if(st.top() != '?')
c[len3++] = st.top() - '';
else c[len3++] = -;
st.pop();
}
printf("Case %d: %I64d\n",cas++,DP());
}
return ;
}

HDU 4294 A Famous Equation(DP)的更多相关文章

  1. HDU 1864 最大报销额(DP)

    题目网址:http://acm.hdu.edu.cn/showproblem.php?pid=1864 题目: 最大报销额 Time Limit: 1000/1000 MS (Java/Others) ...

  2. HDU 2639 Bone Collector II (dp)

    题目链接 Problem Description The title of this problem is familiar,isn't it?yeah,if you had took part in ...

  3. HDU 4562 守护雅典娜(dp)

    守护雅典娜 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submi ...

  4. HDU - 6199 gems gems gems (DP)

    有n(2e4)个宝石两个人轮流从左侧取宝石,Alice先手,首轮取1个或2个宝石,如果上一轮取了k个宝石,则这一轮只能取k或k+1个宝石.一旦不能再取宝石就结束.双方都希望自己拿到的宝石数比对方尽可能 ...

  5. HDU 4249 A Famous Equation(数位DP)

    题目链接:点击打开链接 思路:用d[i][a][b][c][is]表示当前到了第i位, 三个数的i位各自是a,b,c, 是否有进位 , 的方法数. 细节參见代码: #include<cstdio ...

  6. HDU - 6357 Hills And Valleys(DP)

    http://acm.hdu.edu.cn/showproblem.php?pid=6357 题意 给一个数值范围为0-9的a数组,可以选择翻转一个区间,问非严格最长上升子序列,以及翻转的区间. 分析 ...

  7. 2014多校第四场1005 || HDU 4901 The Romantic Hero (DP)

    题目链接 题意 :给你一个数列,让你从中挑选一些数组成集合S,挑另外一些数组成集合T,要求是S中的每一个数在原序列中的下标要小于T中每一个数在原序列中下标.S中所有数按位异或后的值要与T中所有的数按位 ...

  8. hdu 5623 KK's Number(dp)

    问题描述 我们可爱的KK有一个有趣的数学游戏:这个游戏需要两个人,有N\left(1\leq N\leq 5*{10}^{4} \right)N(1≤N≤5∗10​4​​)个数,每次KK都会先拿数.每 ...

  9. hdu 1978 How many ways(dp)

    Problem Description 这是一个简单的生存游戏,你控制一个机器人从一个棋盘的起始点(1,1)走到棋盘的终点(n,m).游戏的规则描述如下: 1.机器人一开始在棋盘的起始点并有起始点所标 ...

随机推荐

  1. linux 安装java环境(jdk)

    第一步:下载jdk-7-linux-i586.tar.gz wget -c http://download.oracle.com/otn-pub/java/jdk/7/jdk-7-linux-i586 ...

  2. HIbernate学习笔记(一) 了解hibernate并搭建环境建立第一个hello world程序

    Hibernate是一个开放源代码的ORM(对象关系映射)框架,它对JDBC进行了轻量级的封装,Java程序员可以使用面向对象的编程思维来操纵数据库,它通过对象属性和数据库表字段之间的映射关系,将对象 ...

  3. linux 密码安全脚本

    #!/bin/bash #by:osx1260@.com DIESO=/etc/pam.d PAMSO=$(ls $DIESO/* |awk -F'/' '{print $4}') NEPAMUN=' ...

  4. Scala学习笔记(二)表达式和函数

    笔记的整理主要针对Scala对比Java的新特性:   1.if表达式 if表达式是有结果返回的. val a= if (5>2) "你好" else 1 a的值为if表达式 ...

  5. HW2.12

    控制台: import java.util.Scanner; public class Solution { public static void main(String[] args) { Scan ...

  6. Codeforces182D - Common Divisors(KMP)

    题目大意 如果把字符串a重复m次可以得到字符串b,那么我们称字符串a为字符串b的一个因子,现在给定两个字符串S1和S2,求它们的公共因子个数 题解 如果它们有公共因子,那么显然它们的最小公共因子肯定是 ...

  7. Worker工作者进程

  8. Oracle数据库自我总结(转)

    Oracle数据库自我总结 1.Oracle连接远程服务器,需要安装客户端的同时需要覆盖D:\oracle\product\10.2.0\db_1\NETWORK\ADMIN\tnsnames.ora ...

  9. light oj 1153 - Internet Bandwidth【网络流无向图】

    1153 - Internet Bandwidth   PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 ...

  10. 换种眼光看Spring之bean是怎么诞生的(一)

    Java的世界里处处存在了对象,有时候换一种眼光往往会给自己带来与之前大不一样的理解. 一个对象的出现离不开字节码,拿classforname来讲,classforname("...&quo ...