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 }