CodeForces 148E Porcelain : 书橱有n层书架,每层书架有一些书,每次取书只能取任意层最左和最右,问取m本书最大价值:dp

预处理dp[i][j]表示i层取j本书最大价值,利用前缀和来处理,枚举不拿的中间一段,这样预处理O(n^3)

随后进行dp,dp[i][j]表示前i层取j本书最大价值,再枚举i层拿k本书,这样也是O(n^3),甚至接近100*10000*100,不过codeforce的速度还是承受住了==

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<algorithm>
 4 using namespace std;
 5 int dp[105][105],Dp[105][10005],sum[105],a[105];
 6 int main()
 7 {
 8   int n,m,i,j,k,maxx,tmp,x;
 9   scanf("%d%d",&n,&m);
10   memset(sum,0,sizeof(sum));
11   memset(dp,0,sizeof(dp));
12   for (i=1;i<=n;i++)
13   {
14     scanf("%d",&a[i]);
15     for (j=1;j<=a[i];j++){
16       scanf("%d",&x);
17       sum[j]=sum[j-1]+x;
18     }
19     for (j=1;j<=a[i];j++)
20       for (k=1;k+a[i]-j-1<=a[i];k++)
21         dp[i][j]=max(dp[i][j],
22             sum[a[i]]-(sum[k+a[i]-j-1]-sum[k-1]));
23   }
24   memset(Dp,0,sizeof(Dp)); tmp=0;
25   for (i=1;i<=n;i++)
26   {
27     tmp+=a[i];
28     for (j=1;j<=tmp;j++)
29     {
30       maxx=0;
31       for (k=0;k<=a[i];k++)
32       {
33         if (j<k) continue;
34         if (tmp-a[i]<j-k) continue;
35         maxx=max(maxx,Dp[i-1][j-k]+dp[i][k]);
36       }
37       Dp[i][j]=maxx;
38     }
39   }
40   printf("%d\n",Dp[n][m]);
41 }
View Code

题目链接:http://codeforces.com/contest/148/problem/E

posted on 2015-03-26 16:47  xiao_xin  阅读(240)  评论(0编辑  收藏  举报

导航