题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1502
题目大意:找出总的满足条件的字符串数,num(a)=num(b)=num(c)且任何前缀均满足num(a)>=num(b)>=num(c)
解题思路:用dp[i][j][k]表示a取i个,b取j个,c取k个的状态下最多有多少种满足条件的情况,容易推得状态转移方程如下:
dp[i][j][k]=dp[i-1][j][k](i>j时)+dp[i][j-1][k](j>k时)+dp[i][j][k-1](k>0时)
根据该状态转移方程即可输出最后的结果dp[n][n][n]
因为本题的数据结果比较大,所以还需要用到高精度,对不会用java的人就只能手敲一个大数相加了。。。
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define scan(a) scanf("%d",&a)
using namespace std;
#define N 61
char dp[N][N][N][],a[];
void init()
{
strcpy(dp[][][],"1\0");
strcpy(dp[][][],"1\0");
strcpy(dp[][][],"0\0");
strcpy(dp[][][],"1\0");
} void add(char *p)
{
int x,l,i,jin=;
l=strlen(a);
int now=;
for(i=;p[i]!='\0';i++)
//从加数开始一位一位访问
{
if(i>=l)
x=p[i]-''+jin;//i超过了a的长度
else
x=p[i]-''+a[i]-''+jin;
if(x>)
{
jin=x/;
x%=;
}
else
jin=;
a[now++]=x+'';
}
while(jin)
{
if(l<=now)
{
a[now++]=(jin%)+'';
jin/=;
}
else
{
x=a[now]-'';
x+=jin;
if(x>)
{
jin=x/;
x%=;
}
else
jin/=;
a[now++]=x+'';
}
}
if(now>l)
a[now]='\0';
} void put(int x)
{
int l=strlen(dp[x][x][x]);
for(int i=l-;i>=;i--)
cout<<dp[x][x][x][i];
cout<<endl<<endl;
} int main()
{
int i,j,k;
int n;
init();
for(i=;i<=;i++)
{
for(j=;j<=i;j++)
{
for(k=;k<=j;k++)
{
a[]='';
a[]='\0';
// cout<<i<<' '<<j<<' '<<k<<endl;
// cout<<dp[i-1][j][k]<<' '<<dp[i][j-1][k]<<' '<<dp[i][j][k-1]<<endl;
if(i>j&&j>=k)
add(dp[i-][j][k]);
if(j>k)
add(dp[i][j-][k]);
if(k>)
add(dp[i][j][k-]);
strcpy(dp[i][j][k],a);
}
}
}
while(~scanf("%d",&n))
{
put(n);
}
return ;
}