一题挺恶心的dp,写了我140行,讲讲思路吧。
状态:dp[len][i][j][k],表示三个数的第len位分别为i,j,k。
限制条件:不能有前导0
转移方程
if((i+j)%10==k)
dp[len][i][j][k]+=dp[len-1][ii][jj][kk];其中ii+jj==kk||ii+jj+1==kk
if((i+j+1)%10==k)
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)
Run ID | Submit Time | Judge Status | Pro.ID | Exe.Time | Exe.Memory | Code Len. | Language | Author |
6275054 | 2012-07-20 12:11:02 | Accepted | 4249 | 93MS | 324K | 2870 B | C++ | Sadly_Snoopy |
#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <stack>
#define LL __int64
using namespace std;
int len1,len2,len3,a[15],b[15],c[15];
LL dp[10][10][10][10];
stack<char> st;
LL DP()
{
memset(dp,0,sizeof(dp));
for(int i=0;i<10;i++)
{
if(a[0]!=-1&&a[0]!=i)
continue;
for(int j=0;j<10;j++)
{
if(b[0]!=-1&&b[0]!=j)
continue;
for(int k=0;k<10;k++)
{
if(c[0]!=-1&&c[0]!=k)
continue;
if((i+j)%10==k)
dp[0][i][j][k]=1;
}
}
}
for(int l=1;l<len3;l++)
{
for(int i=0;i<10;i++)
{
if(a[l]!=-1&&a[l]!=i)
continue;
if(l==len1-1&&i==0)
continue;
if(l>=len1&&i!=0)
continue;
for(int j=0;j<10;j++)
{
if(b[l]!=-1&&b[l]!=j)
continue;
if(l==len2-1&&j==0)
continue;
if(l>=len2&&j!=0)
continue;
for(int k=0;k<10;k++)
{
if(c[l]!=-1&&c[l]!=k)
continue;
if(l==len3-1&&k==0)
continue;
if((i+j)%10!=k&&(i+j+1)%10!=k)
continue;
if((i+j)%10==k)
{
for(int ii=0;ii<10;ii++)
for(int jj=0;jj<10;jj++)
for(int kk=0;kk<10;kk++)
{
if(dp[l-1][ii][jj][kk]!=0&&(ii+jj==kk||ii+jj+1==kk))
dp[l][i][j][k]+=dp[l-1][ii][jj][kk];
}
}
if((i+j+1)%10==k)
{
for(int ii=0;ii<10;ii++)
for(int jj=0;jj<10;jj++)
for(int kk=0;kk<10;kk++)
{
if(dp[l-1][ii][jj][kk]!=0&&(((ii+jj)>=10&&(ii+jj)%10==kk)||((ii+jj+1)>=10&&(ii+jj+1)%10==kk)))
dp[l][i][j][k]+=dp[l-1][ii][jj][kk];
}
}
}
}
}
}
LL ans=0;
for(int i=0;i<10;i++)
for(int j=0;j<10;j++)
for(int k=0;k<10;k++)
{
if(dp[len3-1][i][j][k]!=0&&(i+j==k||i+j+1==k))
ans+=dp[len3-1][i][j][k];
}
return ans;
}
int main()
{
char s[105];
int t=1;
while(~scanf("%s",s))
{
int i=0,len=strlen(s),flag=0;
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
for(;s[i]!='+';i++)
st.push(s[i]);
len1=0;
while(!st.empty())
{
if(st.top()!='?')
a[len1++]=st.top()-'0';
else a[len1++]=-1;
st.pop();
}
for(i++;s[i]!='=';i++)
st.push(s[i]);
len2=0;
while(!st.empty())
{
if(st.top()!='?')
b[len2++]=st.top()-'0';
else b[len2++]=-1;
st.pop();
}
for(i++;i<len;i++)
st.push(s[i]);
len3=0;
while(!st.empty())
{
if(st.top()!='?')
c[len3++]=st.top()-'0';
else c[len3++]=-1;
st.pop();
}
if(len3>=max(len2,len1))
printf("Case %d: %I64d\n",t++,DP());
else printf("Case %d: 0\n",t++);
}
return 0;
}