Codeforces Round #105 (Div. 2) E. Porcelain —— DP(背包问题)
题目链接:http://codeforces.com/problemset/problem/148/E
1 second
256 megabytes
standard input
standard output
During her tantrums the princess usually smashes some collectable porcelain. Every furious shriek is accompanied with one item smashed.
The collection of porcelain is arranged neatly on n shelves. Within each shelf the items are placed in one row, so that one can access
only the outermost items — the leftmost or the rightmost item, not the ones in the middle of the shelf. Once an item is taken, the next item on that side of the shelf can be accessed (see example). Once an item is taken, it can't be returned to the shelves.
You are given the values of all items. Your task is to find the maximal damage the princess' tantrum of m shrieks can inflict on the
collection of porcelain.
The first line of input data contains two integers n (1 ≤ n ≤ 100)
and m (1 ≤ m ≤ 10000).
The next n lines contain the values of the items on the shelves: the first number gives the number of items on this shelf (an integer
between 1 and 100, inclusive),
followed by the values of the items (integers between 1 and 100,
inclusive), in the order in which they appear on the shelf (the first number corresponds to the leftmost item, the last one — to the rightmost one). The total number of items is guaranteed to be at least m.
Output the maximal total value of a tantrum of m shrieks.
2 3
3 3 7 2
3 4 1 5
15
1 3
4 4 3 1 2
9
In the first case there are two shelves, each with three items. To maximize the total value of the items chosen, one can take two items from the left side of the first shelf and one item from the right side of the second shelf.
In the second case there is only one shelf, so all three items are taken from it — two from the left side and one from the right side.
题解:
方法一:
1.对于每个书架,求出每种长度下的首尾相连的最大连续和。
2.通过类似解决背包问题的方法,求得在这些最大连续和的组合下的最大值,即为答案。
方法二:
反向思维:求两边的和最大,即求中间的和最小。
1.对于每个书架,求出每种长度下的最小连续和。
2.通过类似解决背包问题的方法,求得在这些最小连续和的组合下的最小值,然后再用总和减去这个最小值,即为答案。
写法:
i为第i个书架, j为dp到当前待组合的个数, k则为对于每一个书架相应的连续个数。
写法一:从小往大推,此时dp数组需要开二维。
写法二:从大往小推,此时dp数组只需开一维。
注意:写法二必须保证这一阶段的数据只能从上一阶段的数据转移过来, 而不能从同一阶段转移过来,否则会出现重复。
方法一写法一:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const double eps = 1e-;
const int INF = 2e9;
const LL LNF = 9e18;
const int mod = 1e9+;
const int maxn = 1e4+; int n, m;
int dp[][maxn];
int a[][], sum[][], s[][]; void init()
{
scanf("%d%d",&n, &m);
for(int i = ; i<=n; i++)
{
scanf("%d",&a[i][]);
for(int j = ; j<=a[i][]; j++)
scanf("%d",&a[i][j]);
} for(int i = ; i<=n; i++) //求前缀和
for(int j = ; j<=a[i][]; j++)
sum[i][j] = sum[i][j-] + a[i][j]; for(int i = ; i<=n; i++) //求每个书架每种长度下,首尾相连序列的最大连续和
for(int l = ; l<=a[i][]; l++)
for(int r = ; l+r<=a[i][]; r++)
s[i][l+r] = max(s[i][l+r], sum[i][l] + sum[i][a[i][]] - sum[i][a[i][]-r]);
} void solve()
{
for(int i = ; i<=n; i++) //01背包的拓展,每个状态都从O(n)转移过来, 而普通背包则为O(1)
{
for(int j = ; j<=m; j++) //别忘了上一阶段的j状态也参与当前阶段j状态的转移
dp[i][j] = dp[i-][j]; for(int j = ; j<=m; j++)
for(int k = ; k<=min(j,a[i][]); k++)
dp[i][j] = max(dp[i][j], s[i][k]+dp[i-][j-k]);
}
cout<<dp[n][m]<<endl;
} int main()
{
init();
solve();
}
方法一写法二:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const double eps = 1e-;
const int INF = 2e9;
const LL LNF = 9e18;
const int mod = 1e9+;
const int maxn = 1e4+; int n, m;
int dp[maxn];
int a[][], sum[][], s[][]; void init()
{
scanf("%d%d",&n, &m);
for(int i = ; i<=n; i++)
{
scanf("%d",&a[i][]);
for(int j = ; j<=a[i][]; j++)
scanf("%d",&a[i][j]);
} for(int i = ; i<=n; i++)
for(int j = ; j<=a[i][]; j++)
sum[i][j] = sum[i][j-] + a[i][j]; for(int i = ; i<=n; i++)
for(int l = ; l<=a[i][]; l++)
for(int r = ; l+r<=a[i][]; r++)
s[i][l+r] = max(s[i][l+r], sum[i][l] + sum[i][a[i][]] - sum[i][a[i][]-r]);
} void solve()
{
for(int i = ; i<=n; i++)
for(int j = m; j>=; j--)
for(int k = ; k<=min(j,a[i][]); k++)
dp[j] = max(dp[j], s[i][k]+dp[j-k]); cout<<dp[m]<<endl;
} int main()
{
init();
solve();
}
方法二写法一:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const double eps = 1e-;
const int INF = 2e9;
const LL LNF = 9e18;
const int mod = 1e9+;
const int maxn = 1e4+; int n, m, all;
int dp[][maxn];
int a[][], sum[][], s[][]; void init()
{
scanf("%d%d",&n, &m);
m = -m;
for(int i = ; i<=n; i++)
{
scanf("%d",&a[i][]);
for(int j = ; j<=a[i][]; j++)
scanf("%d",&a[i][j]), all += a[i][j];
m += a[i][];
} for(int i = ; i<=n; i++) //前缀和
for(int j = ; j<=a[i][]; j++)
sum[i][j] = sum[i][j-] + a[i][j]; for(int i = ; i<=n; i++) //最小连续和,因为“最小”,所以需要初始化为最大
for(int j = ; j<=a[i][]; j++)
s[i][j] = INF; for(int i = ; i<=n; i++) //求最小连续和
for(int j = ; j<=a[i][]; j++)
for(int k = ; k<=j; k++)
s[i][j-k+] = min(s[i][j-k+], sum[i][j]-sum[i][k-]);
} void solve()
{
for(int i = ; i<=n; i++) //需要所有都初始化为最大
for(int j = ; j<=m; j++)
dp[i][j] = INF; for(int i = ; i<=n; i++)
{
for(int j = ; j<=m; j++)
dp[i][j] = dp[i-][j]; for(int j = ; j<=m; j++)
for(int k = ; k<=min(j,a[i][]); k++)
dp[i][j] = min(dp[i][j], s[i][k]+dp[i-][j-k]);
}
cout<<all - dp[n][m]<<endl;
} int main()
{
init();
solve();
}
方法二写法二:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const double eps = 1e-;
const int INF = 2e9;
const LL LNF = 9e18;
const int mod = 1e9+;
const int maxn = 1e4+; int n, m, all;
int dp[maxn];
int a[][], sum[][], s[][]; void init()
{
scanf("%d%d",&n, &m);
m = -m;
for(int i = ; i<=n; i++)
{
scanf("%d",&a[i][]);
for(int j = ; j<=a[i][]; j++)
scanf("%d",&a[i][j]), all += a[i][j];
m += a[i][];
} for(int i = ; i<=n; i++)
for(int j = ; j<=a[i][]; j++)
sum[i][j] = sum[i][j-] + a[i][j]; for(int i = ; i<=n; i++)
for(int j = ; j<=a[i][]; j++)
s[i][j] = INF; for(int i = ; i<=n; i++)
for(int j = ; j<=a[i][]; j++)
for(int k = ; k<=j; k++)
s[i][j-k+] = min(s[i][j-k+], sum[i][j]-sum[i][k-]);
} void solve()
{
for(int j = ; j<=m; j++)
dp[j] = INF; for(int i = ; i<=n; i++)
for(int j = m; j>=; j--)
for(int k = ; k<=min(j,a[i][]); k++)
dp[j] = min(dp[j], s[i][k]+dp[j-k]); cout<<all-dp[m]<<endl;
} int main()
{
init();
solve();
}
Codeforces Round #105 (Div. 2) E. Porcelain —— DP(背包问题)的更多相关文章
- 水题 Codeforces Round #105 (Div. 2) B. Escape
题目传送门 /* 水题:这题唯一要注意的是要用double,princess可能在一个小时之内被dragon赶上 */ #include <cstdio> #include <alg ...
- Codeforces Round #105 (Div. 2) D. Bag of mice 概率dp
题目链接: http://codeforces.com/problemset/problem/148/D D. Bag of mice time limit per test2 secondsmemo ...
- Codeforces Round #260 (Div. 1) A - Boredom DP
A. Boredom Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/455/problem/A ...
- Codeforces Round #131 (Div. 1) B. Numbers dp
题目链接: http://codeforces.com/problemset/problem/213/B B. Numbers time limit per test 2 secondsmemory ...
- Codeforces Round #131 (Div. 2) B. Hometask dp
题目链接: http://codeforces.com/problemset/problem/214/B Hometask time limit per test:2 secondsmemory li ...
- Codeforces Round #276 (Div. 1) D. Kindergarten dp
D. Kindergarten Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/problemset/proble ...
- Codeforces Round #105 (Div. 2) ABCDE
A. Insomnia cure 哎 只能说英语太差,一眼题我看了三分钟. 题意:给5个数k, l, m, n 和 d,求1~d中能被k, l, m, n 至少一个整除的数的个数. 题解:…… 代码: ...
- Codeforces Round #533 (Div. 2) C.思维dp D. 多源BFS
题目链接:https://codeforces.com/contest/1105 C. Ayoub and Lost Array 题目大意:一个长度为n的数组,数组的元素都在[L,R]之间,并且数组全 ...
- Codeforces Round #539 (Div. 2) 异或 + dp
https://codeforces.com/contest/1113/problem/C 题意 一个n个数字的数组a[],求有多少对l,r满足\(sum[l,mid]=sum[mid+1,r]\), ...
随机推荐
- cmake使用(CMakeList.txt)
set(CMAKE_INCLUDE_CURRENT_DIR ON)#CMAKE_INCLUDE_CURRENT_DIR equal to INCLUDE_DIRECTORY(${CMAKE_CURRE ...
- List遍历时删除遇到的问题
这周在开发中遇到了一个以前没遇到的小Bug,在这里记录下来. List集合,我们平时都经常使用.但是,我在遍历List集合时,调用了List集合的remove方法来删除集合中的元素,简单的代码结构是这 ...
- 用JSONObject解析和处理json数据
(一)jar包下载 所需jar包打包下载百度网盘地址:https://pan.baidu.com/s/1c27Uyre (二)常见场景及处理方法 1.解析简单的json字符串: 1 // 简单的jso ...
- Android自定义控件之自定义组合控件(三)
前言: 前两篇介绍了自定义控件的基础原理Android自定义控件之基本原理(一).自定义属性Android自定义控件之自定义属性(二).今天重点介绍一下如何通过自定义组合控件来提高布局的复用,降低开发 ...
- 在谈MVP之前,你真的懂MVC吗?
最近看到很多文章在谈论MVP或者MVVM模式的,但其实无论MVP还是MVVM都只是MVC模式的一种变种.而如果你对MVC的设计理念都还没有理解透彻,那么即使换成MVP亦或MVVM也不可能让你杂乱不堪的 ...
- vdWebControl.js去水印
vdWebControl.js可以在浏览器中展示cad图形(须要使用其自家的转换工具把cad转换为vds格式.工具免费,但转换完成后的文件带水印信息),支持编辑图形. vdWebControl.js试 ...
- RecyclerView onItemClick button和布局都有单击事件时的处理方式
RecyclerView为了给开发人员提供更大的自由度.没有默认的提供onItemClick接口. 网上有一种比較简单的实现方式 , 适用于不须要针对item里面某个button做特殊处理的情况 我眼 ...
- Optimizer统计信息管理介绍
1. 前言 在我们的日常维护中受理一些一直以来运行得非常好的系统,突然有一天用户反馈没有做不论什么操作,系统的某个功能模块或者是某个报表曾经仅仅须要几秒.但如今须要几分钟或更长的时间都没有返回结 ...
- vue2.0 自定义指令
Vue指令 Vue的指令以v-开头,作用在HTML元素上,将指令绑定在元素上,给绑定的元素添加一些特殊行为. 例如: <h1 v-if="yes">Yes</h1 ...
- odoo费用报销流程