HDOJ 4249 A Famous Equation DP

DP:

DP[len][k][i][j] 再第len位,第一个数len位为i,第二个数len位为j,和的第len位为k

每一位可以从后面一位转移过来,可以进位也可以不进位

A Famous Equation

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 500    Accepted Submission(s): 147

Problem Description

Mr. B writes an addition equation such as 123+321=444 on the blackboard after class. Mr. G removes some of the digits and makes it look like “1?3+??1=44?”. Here “?” denotes removed digits. After Mr. B realizes some digits are missing, he wants to recover them.
Unfortunately, there may be more than one way to complete the equation. For example “1?3+??1=44?” can be completed to “123+321=444” , “143+301=444” and many other possible solutions. Your job is to determine the number of different possible solutions.

Input

Each test case describes a single line with an equation like a+b=c which contains exactly one plus sign “+” and one equal sign “=” with some question mark “?” represent missing digits. You may assume a, b and c are non-negative integers, and the length of each
number is no more than 9. In the other words, the equation will contain three integers less than 1,000,000,000.

Output

For each test case, display a single line with its case number and the number of possible solutions to recover the equation.

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.

Source

Fudan Local Programming Contest 2012

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <stack>

using namespace std;

typedef long long int LL;

char cpp[200];
int a[200],len1,b[200],len2,c[200],len3;
LL dp[20][20][20][20];

int main()
{
    int cas=1;
    while(cin>>cpp)
    {
        len1=len2=len3=0;
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        memset(c,0,sizeof(c));
        int n=strlen(cpp);
        int i; stack<char> stk;
        for(i=0;i<n;i++)
        {
            if(cpp[i]=='+')
            {
                while(!stk.empty())
                {
                    char c=stk.top(); stk.pop();
                    if(c!='?') a[len1++]=c-'0';
                    else a[len1++]=-1;
                }
                i++;
                break;
            }
            stk.push(cpp[i]);
        }
        for(;i<n;i++)
        {
            if(cpp[i]=='=')
            {
                while(!stk.empty())
                {
                    char c=stk.top(); stk.pop();
                    if(c!='?') b[len2++]=c-'0';
                    else b[len2++]=-1;
                }
                i++;
                break;
            }
            stk.push(cpp[i]);
        }
        for(;i<n;i++) stk.push(cpp[i]);
        while(!stk.empty())
        {
            char cc=stk.top(); stk.pop();
            if(cc!='?') c[len3++]=cc-'0';
            else c[len3++]=-1;
        }

        for(int i=len1-1;i>0;i--) if(a[i]==0) len1--; else break;
        for(int i=len2-1;i>0;i--) if(b[i]==0) len2--; else break;
        for(int i=len3-1;i>0;i--) if(c[i]==0) len3--; else break;

        memset(dp,0,sizeof(dp));

        ///len==0
        for(int i=0;i<=9;i++)
        {
            if(a[0]==-1||a[0]==i)
            for(int j=0;j<=9;j++)
            {
                if(b[0]==-1||b[0]==j)
                for(int k=0;k<=9;k++)
                if(c[0]==-1||c[0]==k)
                {
                    if(k==(i+j)%10)
                        dp[0][k][i][j]=1;
                }
            }
        }
        ///len=1...
        for(int len=1;len<len3;len++)
        {
            for(int i=0;i<=9;i++)
            {
                if(len==len1-1&&i==0) continue;
                if(len>=len1&&i!=0) continue;
                if(a[len]==-1||a[len]==i)
                for(int j=0;j<=9;j++)
                {
                    if(len==len2-1&&j==0) continue;
                    if(len>=len2&&j!=0) continue;
                    if(b[len]==-1||b[len]==j)
                    for(int k=0;k<=9;k++)
                    {
                        if(len==len3-1&&k==0) continue;
                        if(((i+j)%10!=k)&&((i+j+1)%10!=k))
                                continue;
                        if(c[len]==-1||c[len]==k)
                        {
                            ///没有进位
                            if((i+j)%10==k)
                            {
                                for(int ii=0;ii<=9;ii++)
                                    for(int jj=0;jj<=9;jj++)
                                        for(int kk=0;kk<=9;kk++)
                                        {
                                            if((ii+jj==kk)||(ii+jj+1==kk))
                                                dp[len][k][i][j]+=dp[len-1][kk][ii][jj];
                                        }
                            }
                            ///有进位
                            if((i+j+1)%10==k)
                            {
                                 for(int ii=0;ii<=9;ii++)
                                    for(int jj=0;jj<=9;jj++)
                                        for(int kk=0;kk<=9;kk++)
                                        {
                                            if(((ii+jj>=10)&&(ii+jj)%10==kk)||((ii+jj+1>=10)&&(ii+jj+1)%10==kk))
                                                dp[len][k][i][j]+=dp[len-1][kk][ii][jj];
                                        }
                            }
                        }
                    }
                }
            }
        }
        LL ans=0;
        int mx=max(len1,max(len2,len3));
        for(int i=0;i<=9;i++)
            for(int j=0;j<=9;j++)
                for(int k=0;k<=9;k++)
                    if((i+j==k)||(i+j+1==k))
                    {
                        if(mx==1&&i+j!=k) continue;
                        ans+=dp[mx-1][k][i][j];
                    }
        cout<<"Case "<<cas++<<": "<<ans<<endl;
        memset(cpp,0,sizeof(cpp));
    }
    return 0;
}
时间: 2024-08-10 12:38:34

HDOJ 4249 A Famous Equation DP的相关文章

HDU 4249 A Famous Equation(数位DP)

题目链接:点击打开链接 思路:用d[i][a][b][c][is]表示当前到了第i位, 三个数的i位分别是a,b,c, 是否有进位 , 的方法数. 细节参见代码: #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<string> #include<vector> #include<stack> #includ

HDU-4249-A Famous Equation(DP)

Problem Description Mr. B writes an addition equation such as 123+321=444 on the blackboard after class. Mr. G removes some of the digits and makes it look like "1?3+??1=44?". Here "?" denotes removed digits. After Mr. B realizes some

hdoj 2391 Filthy Rich 【DP】

题目大意:有个二维数组,你从(0,0)出发,最终到(n,m), 在这个二维数组中,每个位置dp[i][j]都有一定量的黄金,你可以拾取,问你最多能失去多少,并且,你的方向有下,右, 斜向下三个方向: 策略:就是每一个都加上它的上方向与左方向的最大值,这样到最后就是最大值.详情见代码 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2391 代码: #include<stdio.h> #include<string.h> int dp[1

hdoj 4901 The Romantic Hero DP hdoj 4902 Nice boat 线段树

惨遭丽洁乱虐..这一场也是比得乱七八糟的,4902本是丽洁定义比较难的题,结果数据随机的,被许多暴力水过了..4905考察的是四边形不等式优化,但是这道题的dp方程实际上不满足该优化的条件..朴素的o(n^3)会超时,所以这题目前是没有正解了..我还写了个这题的贪心,强度挺高,可以对大概一半数据,错的误差也只有个位数,还揪出官方第五个数据..朴素dp和贪心跑这个数据都比官方数据多了1,也就证明这题不满足四边形不等式优化的条件.. http://acm.hdu.edu.cn/showproblem

HDOJ 4248 A Famous Stone Collector DP

DP: dp[i][j]前i堆放j序列长度有多少行法, dp[i][j]=dp[i-1][j] (不用第i堆), dp[i][j]+=dp[i-1][j-k]*C[j][k] (用第i堆的k个石头) A Famous Stone Collector Time Limit: 30000/15000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 845    Accepted Su

HDOJ 5325 Crazy Bobo 树形DP

按照升序或者降序选择的点集可以满足条件..... 树上的每个节点可以从子节点转移,也可以从父亲节点转移 Crazy Bobo Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) Total Submission(s): 325    Accepted Submission(s): 100 Problem Description Bobo has a tree,whose vert

HDOJ 5119 Happy Matt Friends DP

N*M暴力DP.... Happy Matt Friends Time Limit: 6000/6000 MS (Java/Others)    Memory Limit: 510000/510000 K (Java/Others) Total Submission(s): 82    Accepted Submission(s): 34 Problem Description Matt has N friends. They are playing a game together. Each

HDOJ 4252 A Famous City 单调栈

单调栈: 维护一个单调栈 A Famous City Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1671    Accepted Submission(s): 644 Problem Description After Mr. B arrived in Warsaw, he was shocked by the skyscrap

HDOJ 4251 The Famous ICPC Team Again

划分树水题..... The Famous ICPC Team Again Time Limit: 30000/15000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 859    Accepted Submission(s): 415 Problem Description When Mr. B, Mr. G and Mr. M were preparing for the