HDU 1502 Regular Words DP+高精度

题目链接: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的人就只能手敲一个大数相加了。。。

  1 #include<cmath>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<iostream>
  5 #include<algorithm>
  6 #define scan(a) scanf("%d",&a)
  7 using namespace std;
  8 #define N 61
  9 char dp[N][N][N][100],a[100];
 10 void init()
 11 {
 12     strcpy(dp[0][0][0],"1");
 13     strcpy(dp[1][1][0],"1");
 14     strcpy(dp[1][0][1],"0");
 15     strcpy(dp[1][0][0],"1");
 16 }
 17 
 18 void add(char *p)
 19 {
 20     int x,l,i,jin=0;
 21     l=strlen(a);
 22     int now=0;
 23     for(i=0;p[i]!='';i++)
 24     //从加数开始一位一位访问
 25     {
 26         if(i>=l)
 27             x=p[i]-'0'+jin;//i超过了a的长度
 28         else
 29             x=p[i]-'0'+a[i]-'0'+jin;
 30         if(x>9)
 31         {
 32             jin=x/10;
 33             x%=10;
 34         }
 35         else
 36             jin=0;
 37         a[now++]=x+'0';
 38     }
 39     while(jin)
 40     {
 41         if(l<=now)
 42         {
 43             a[now++]=(jin%10)+'0';
 44             jin/=10;
 45         }
 46         else
 47         {
 48             x=a[now]-'0';
 49             x+=jin;
 50             if(x>10)
 51             {
 52                 jin=x/10;
 53                 x%=10;
 54             }
 55             else
 56                 jin/=10;
 57             a[now++]=x+'0';
 58         }
 59     }
 60     if(now>l)
 61         a[now]='';
 62 }
 63 
 64 void put(int x)
 65 {
 66     int l=strlen(dp[x][x][x]);
 67     for(int i=l-1;i>=0;i--)
 68         cout<<dp[x][x][x][i];
 69     cout<<endl<<endl;
 70 }
 71 
 72 int main()
 73 {
 74     int i,j,k;
 75     int n;
 76     init();
 77     for(i=1;i<=60;i++)
 78     {
 79         for(j=0;j<=i;j++)
 80         {
 81             for(k=0;k<=j;k++)
 82             {
 83                 a[0]='0';
 84                 a[1]='';
 85                 // cout<<i<<' '<<j<<' '<<k<<endl;
 86                 // cout<<dp[i-1][j][k]<<' '<<dp[i][j-1][k]<<' '<<dp[i][j][k-1]<<endl;
 87                 if(i>j&&j>=k)
 88                     add(dp[i-1][j][k]);
 89                 if(j>k)
 90                     add(dp[i][j-1][k]);
 91                 if(k>0)
 92                     add(dp[i][j][k-1]);
 93                 strcpy(dp[i][j][k],a);
 94             }
 95         }
 96     }
 97     while(~scanf("%d",&n))
 98     {
 99         put(n);
100     }
101     return 0;
102 }
View Code
原文地址:https://www.cnblogs.com/wuwing/p/3606438.html