USACO 4.3 Buy Low, Buy Lower(dp)

关于去重没想去怎么弄,查的题解。。。基本完全抄袭的题解。。。令dp[n+1] = 0,求dp[n+1]即可。。存4位的高精度,第一次写。。dp[i][0]存长度。

  1 /*

  2 ID:cuizhe

  3 LANG: C++

  4 TASK: buylow

  5 */

  6 #include <cstdio>

  7 #include <cmath>

  8 #include <cstring>

  9 #include <iostream>

 10 #include <map>

 11 using namespace std;

 12 int p[5003],o[5003],dp[5003][401];

 13 int next[5003];

 14 int main()

 15 {

 16     int i,n,j,k,maxz,flag = 1,z;

 17     freopen("buylow.in","r",stdin);

 18     freopen("buylow.out","w",stdout);

 19 

 20     scanf("%d",&n);

 21     for(i = 1; i <= n; i ++)

 22         scanf("%d",&p[i]);

 23     n ++;

 24     for(i = 1; i <= n; i ++)

 25     {

 26         maxz = 0;

 27         for(j = 1; j < i; j ++)

 28         {

 29             if(p[j] > p[i])

 30             {

 31                 if(maxz < o[j])

 32                     maxz = o[j];

 33             }

 34         }

 35         o[i] = maxz + 1;

 36         flag = max(o[i],flag);

 37     }

 38     for(i = 1;i < n;i ++)

 39     {

 40         for(j = i+1;j <= n;j ++)

 41         {

 42             if(p[i] == p[j])

 43             {

 44                 next[i] = j;

 45                 break;

 46             }

 47         }

 48     }

 49     for(i = 1; i <= n; i ++)

 50     {

 51         for(j = 1; j < i; j ++)

 52         {

 53             if(p[j] > p[i])

 54             {

 55                 if((next[j] == 0||next[j] > i)&&o[i] == o[j]+1)

 56                 {

 57                     int len;

 58                     len = max(dp[i][0],dp[j][0]);

 59                     for(k = 1;k <= len;k ++)

 60                     {

 61                         dp[i][k] += dp[j][k];

 62                     }

 63                     for(k = 1;k <= len;k ++)

 64                     {

 65                         if(dp[i][k] >= 10000)

 66                         {

 67                             dp[i][k+1] += dp[i][k]/10000;

 68                             dp[i][k] = dp[i][k]%10000;

 69                             if(k+1 > len)

 70                             len = k+1;

 71                         }

 72                     }

 73                     dp[i][0] = len;

 74                 }

 75             }

 76         }

 77         if(dp[i][0] == 0)

 78         {

 79             dp[i][0] = 1;

 80             dp[i][1] = 1;

 81         }

 82     }

 83     printf("%d ",flag-1);

 84     z = 1;

 85     for(i = dp[n][0];i >= 1;i --)

 86     {

 87         if(dp[n][i] >= 1000||z)

 88         printf("%d",dp[n][i]);

 89         else if(dp[n][i] >= 100)

 90         printf("0%d",dp[n][i]);

 91         else if(dp[n][i] >= 10)

 92         printf("00%d",dp[n][i]);

 93         else

 94         printf("000%d",dp[n][i]);

 95         if(i != dp[n][i])

 96         z = 0;

 97     }

 98     printf("\n");

 99     return 0;

100 }

 

你可能感兴趣的:(USACO)