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<=nS_i=1,1<=i<=nSi​=1,1<=i<=n。

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

Analysis

  • 有nnn行,n∈[1,100]n\in[1,100]n∈[1,100],每行个数有可能不同。
  • 一共购买mmm个物品,m∈[1,10000]m\in[1,10000]m∈[1,10000]
  • 每行可以购买前iii个物品和后jjj个物品,i,j∈[0,100]i,j \in [0,100]i,j∈[0,100]

Solution

容易发现,每行的最优都可以单独预处理算出,而当每行购买iii个商品的最大价值确定后,就可以转换为一个多重背包问题。

于是预处理每一行的购买iii件商品的最大价值。

设在该行一共有s个商品,购买k个商品,在左边购买m个商品,则在右边购买k−m个商品设在该行一共有s个商品,购买k个商品,在左边购买m个商品,则在右边购买k-m个商品设在该行一共有s个商品,购买k个商品,在左边购买m个商品,则在右边购买k−m个商品

容易得到:

val[k]=∑m=0k(∑i=1mvali+∑j=s−(k−m)+1svalj)val[k] = \sum_{m=0}^k (\sum_{i=1}^m val_i +\sum_{j=s-(k-m)+1}^s val_j)val[k]=∑m=0k​(∑i=1m​vali​+∑j=s−(k−m)+1s​valj​)

当然,区间和我们可以用简单的前缀和算出:

for(int i = 1;i<=s;++i)//处理前缀和为以后求区间和做准备
sum[i] = sum[i-1] + val[i];

于是上式可以简化成:

设s个商品在左边取了m个,在右边取了k−m个设s个商品在左边取了m个,在右边取了k-m个设s个商品在左边取了m个,在右边取了k−m个

val[k]=summ+sums−sums−(k−m)val[k] = sum_m + sum_s - sum_{s-(k-m)}val[k]=summ​+sums​−sums−(k−m)​

前缀和求区间和:sum[i,j]=sumj−sumi−1sum_{[i,j]}=sum_j-sum_{i-1}sum[i,j]​=sumj​−sumi−1​

由于数据量小,可以直接枚举这个m,得到此时的最大价值。

那么我们就可以用O(s)的复杂度预处理,随后用O(s2s^2s2)的复杂度求出该商品购买所有件数时的最大价值。

其中s∈[1,100]s\in[1,100]s∈[1,100],有nnn种商品,n∈[1,100]n\in[1,100]n∈[1,100],每种都需要O(s2)O(s^2)O(s2)进行预处理,复杂度可能达到O(ns2)O(ns^2)O(ns2)但由于常数很小,还是可以接受的。

	for(register int k = 1;k<=n;++k)//第k种
for(register int i = 1;i<=s[k][0];++i)
//表示取i个的时候,s[k][0]代表该商品总个数
for(register int j = 0;j<=i;++j)
dp[k][i] = MAX(dp[k][i],\
sum[k][j] + sum[k][s[k][0]] - sum[k][s[k][0] - i + j]);

接下来就是多重背包问题了:

有n种商品,每种商品有pi个,第i种商品取j个得到的最大价值为sij,有n种商品,每种商品有p_i个,第i种商品取j个得到的最大价值为s_{ij},有n种商品,每种商品有pi​个,第i种商品取j个得到的最大价值为sij​,

每个商品的体积都为1,容量为m,问最多能取得多大价值。每个商品的体积都为1,容量为m,问最多能取得多大价值。每个商品的体积都为1,容量为m,问最多能取得多大价值。

	//dp[i][j]代表在第i行取j个商品的最大获利
//f[i][j]代表在前i行取j个商品
for(register int i = 1;i<=n;++i) //在第i行选商品
for(register int j = 1;j<=m;++j)//此时一共选择j个商品
for(register int k = 0;k<=s[i][0] && k <= j;++k)
{
//k是在这一行取得多少商品,注意k不能超过当前取商品量
//当前在前i行取j个商品,在当前行取k个商品,那么就在前i-1行取j-k个商品
dp[i][j] = MAX(dp[i][j],dp[i-1][j-k] + f[i][k]);
}

本题结束。

Code

#include <cstdio>
#define MAX(x,y) ((x)>(y)?(x):(y))
using namespace std;
void read(int &r)
{
static char c;
for(c=getchar();c>'9'||c<'0';c=getchar());
for(;c<='9'&&c>='0';r=(r<<1)+(r<<3)+c-48,c=getchar());
}
int n,m;
int s[105][105];
int dp[105][10005];//表示从第i排取出j个的最大价值和
int f[105][105];
int sum[105][105];
int main()
{
read(n);
read(m);
for(register int i = 1;i<=n;++i)
{
read(s[i][0]);
for(register int j = 1;j<=s[i][0];++j)
read(s[i][j]);
} for(register int i = 1;i<=n;++i)//处理前缀和为以后求区间和做准备
for(register int j = 1;j<=s[i][0];++j)
sum[i][j] = sum[i][j-1] + s[i][j]; //每行按行dp算出取n个商品时的最大值
for(register int k = 1;k<=n;++k)
for(register int i = 1;i<=s[k][0];++i) //表示取i个的时候
for(register int j = 0;j<=i;++j)
f[k][i] = MAX(f[k][i],sum[k][j] + sum[k][s[k][0]] - sum[k][s[k][0] - i + j]);
//在左边取j个,右边取 i - j个
//使用前缀和的方法求区间 //f[i][j]代表在第i行取j个商品的最大获利
//dp[i][j]代表在前i行取j个商品
for(register int i = 1;i<=n;++i) //在第i行选商品
for(register int j = 1;j<=m;++j)//此时一共选择j个商品
for(register int k = 0;k<=s[i][0] && k <= j;++k)
{
//k是在这一行取得多少商品,注意k不能超过当前取商品量
//当前在前i行取j个商品,在当前行取k个商品,那么就在前i-1行取j-k个商品
dp[i][j] = MAX(dp[i][j],dp[i-1][j-k] + f[i][k]);
}
printf("%d",dp[n][m]);
return 0;
}

[JZOJ]3413.KC的瓷器的更多相关文章

  1. noip2018 pre——Dp

    Dp专题 1011: KC的瓷器 (porcelain) 题目描述 KC来到了一个盛产瓷器的国度.他来到了一位商人的店铺.在这个店铺中,KC看到了一个有n(1<=n<=100)排的柜子,每 ...

  2. (jzoj snow的追寻)线段树维护树的直径

    jzoj snow的追寻 DFS序上搞 合并暴力和,记录最长链和当前最远点,距离跑LCA # include <stdio.h> # include <stdlib.h> # ...

  3. [jzoj]3506.【NOIP2013模拟11.4A组】善良的精灵(fairy)(深度优先生成树)

    Link https://jzoj.net/senior/#main/show/3506 Description 从前有一个善良的精灵. 一天,一个年轻人B找到她并请他预言他的未来.这个精灵透过他的水 ...

  4. [jzoj]3468.【NOIP2013模拟联考7】OSU!(osu)

    Link https://jzoj.net/senior/#main/show/3468 Description osu 是一款群众喜闻乐见的休闲软件. 我们可以把osu的规则简化与改编成以下的样子: ...

  5. [jzoj]5478.【NOIP2017提高组正式赛】列队

    Link https://jzoj.net/senior/#main/show/5478 Description Sylvia 是一个热爱学习的女孩子.       前段时间,Sylvia 参加了学校 ...

  6. [jzoj]1115.【HNOI2008】GT考试

    Link https://jzoj.net/senior/#main/show/1115 Description 申准备报名参加GT考试,准考证号为n位数X1X2X3...Xn-1Xn(0<=X ...

  7. [jzoj]2538.【NOIP2009TG】Hankson 的趣味题

    Link https://jzoj.net/senior/#main/show/2538 Description Hanks 博士是BT (Bio-Tech,生物技术) 领域的知名专家,他的儿子名叫H ...

  8. [jzoj]4216.【NOIP2015模拟9.12】平方和

    Link https://jzoj.net/senior/#main/show/4216 Description 给出一个N个整数构成的序列,有M次操作,每次操作有一下三种: ①Insert Y X, ...

  9. [jzoj]2938.【NOIP2012模拟8.9】分割田地

    Link https://jzoj.net/senior/#main/show/2938 Description 地主某君有一块由2×n个栅格组成的土地,有k个儿子,现在地主快要终老了,要把这些土地分 ...

随机推荐

  1. 「BJOI2018」求和

    「BJOI2018」求和 传送门 观察到 \(k\) 很小而且模数不会变,所以我们直接预处理 \(k\) 取所有值时树上前缀答案,查询的时候差分一下即可. 参考代码: #include <alg ...

  2. [转载]Spring下IOC容器和DI(依赖注入) @Bean及@Autowired

    Spring下IOC容器和DI(依赖注入) @Bean及@Autowired自动装配 bean是什么 bean在spring中可以理解为一个对象.理解这个对象需要换一种角度,即可将spring看做一门 ...

  3. Jquery - ajax url路径问题

    Jquery - ajax url路径问题 2016年04月26日 09:59:27 yuxuac 阅读数 32308    版权声明:本文为博主原创文章,未经博主允许不得转载. https://bl ...

  4. oracle练习-day02

    .查询员工表和部门表.查询出雇员的编号,姓名,部门的编号和名称,地址.查询出每个员工的上级领导.在上一个例子的基础上查询该员工的部门名称.在上一个例子的基础上查询员工工资等级和他的上级领导工资等级.查 ...

  5. docker学习笔记-05:Docker安装mysql和redis

    一.安装mysql 1.docker hub 上查找mysql镜像 docker search mysql 2.从docker hub (使用阿里云加速器)拉取mysql镜像到本地标签为5.6 doc ...

  6. Day1-Luogu-2085

    题目描述 有n个函数,分别为F1,F2,...,Fn.定义Fi(x)=Ai*x^2+Bi*x+Ci (x∈N*).给定这些Ai.Bi和Ci,请求出所有函数的所有函数值中最小的m个(如有重复的要输出多个 ...

  7. 六 Hibernate多表操作&级联&外键维护

    Hibernate的一对多关联映射 Hibernate的多对多关联映射 数据库表与表之间的关系:一对多,多对多,一对一 一对多:一个部门对应多个员工,一个员工只能属于一个部门.一个客户对应多个联系人, ...

  8. 吴裕雄--天生自然JAVA数据库编程:SQL常用语句基础

    DROP TABLE user ; -- 删除表 CREATE TABLE user( id INT AUTO_INCREMENT PRIMARY KEY , name ) NOT NULL , pa ...

  9. Samjia 和矩阵[loj6173](Hash+后缀数组)

    传送门 本题要求本质不同的子矩阵,即位置不同也算相同(具体理解可以看样例自己yy). 我们先看自己会什么,我们会求一个字符串中不同的子串的个数.我们考虑把子矩阵变成一个字符串. 先枚举矩阵的宽度,记为 ...

  10. C++ 类 与 static

    背景 从学习C++到使用现在,发现很多新的东西,正好整理一下. static 为静态,指是当类编译加载的时候,内存就会开辟存储空间的. static 数据成员 在类中,static 可修饰 类中的成员 ...