JZOJ 3413. 【NOIP2013模拟】KC的瓷器

题目

Description

KC来到了一个盛产瓷器的国度。他来到了一位商人的店铺。在这个店铺中,KC看到了一个有n(1<=n<=100)排的柜子,每排都有一些瓷器,每排不超过100个。那些精美的艺术品使KC一下心动了,决定从N排的商品中买下m(1<=m<=10000)个瓷器。

这个商人看KC的脸上长满了痘子,就像苔藓一样,跟精美的瓷器相比相差太多,认为这么精致的艺术品被这样的人买走艺术价值会大打折扣。商人感到不爽,于是规定每次取商品只能取其中一排的最左边或者最右边那个,想为难KC。

现在KC又获知每个瓷器的价值(用一个不超过100的正整数表示),他希望取出的m个商品的总价值最大。
 

Input

输入文件的第一行包括两个正整数n,m;

接下来2到n+1行,第i行第一个数表示第i排柜子的商品数量Si,接下来Si个数表示从左到右每个商品的价值。

Output

输出文件只有一个正整数,即m个商品最大的总价值。
 

Sample Input

输入1:
2 3
3 3 7 2
3 4 1 5

输入2:
1 3
4 4 3 1 2
 

Sample Output

输出1:
15
样例解释1:
取第一排的最左边两个和第二排的最右边那个。总价直为3+7+5=15;

输出2:
9
 
 

Data Constraint

对于10%的数据,Si=1,1<=i<=n。

对于另外10%的数据,n=1.

 

分析

  •   显然DP

  • 预处理每行选j个的答案

 

代码

 1 #include <cmath>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <iostream>
 5 #include <algorithm>
 6 #define ll long long
 7 using namespace std;
 8 int a[120][120],f[120][10001],sum1[120][120],sum2[120][120],d[120][120];
 9 
10 int main()
11 {
12     int n,m;
13     cin>>n>>m;
14     for (int i=1,x;i<=n;i++)
15     {
16         cin>>a[i][0];
17         a[i][110]=a[i-1][110]+a[i][0];
18         for (int j=1;j<=a[i][0];j++)
19         {
20             cin>>a[i][j];
21             sum1[i][j]=sum1[i][j-1]+a[i][j];
22         }
23         for (int j=a[i][0],k=1;j>=1;j--,k++)
24             sum2[i][k]=sum2[i][k-1]+a[i][j];
25     }
26     for (int i=1;i<=n;i++)
27         for (int j=1;j<=min(a[i][0],m);j++)
28             for (int k=0;k<=j;k++)
29                 d[i][j]=max(d[i][j],sum1[i][k]+sum2[i][j-k]);
30     for (int i=1;i<=n;i++)
31         for (int j=1;j<=a[i][110];j++)
32             for (int k=0;k<=min(a[i][0],j);k++)
33                 f[i][j]=max(f[i][j],f[i-1][j-k]+d[i][k]);
34     cout<<f[n][m];
35     return 0;
36 }
原文地址:https://www.cnblogs.com/zjzjzj/p/11773530.html