• 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
  • 相关阅读:
    [NOIp2009] $Hankson$ 的趣味题
    [洛谷P1730] 最小密度路径
    [NOIp2015] 运输计划
    [NOIp2012] 借教室
    [NOIp2012] 国王游戏
    [NOIp2016] 蚯蚓
    [洛谷P1272] 重建道路
    [洛谷P1273] 有线电视网
    [ZJOI2010] 数字计数
    ☆ [HDU2089] 不要62「数位DP」
  • 原文地址:https://www.cnblogs.com/wuwing/p/3606438.html
Copyright © 2020-2023  润新知