LUOGU P4095 [HEOI2013]Eden 的新背包问题
题目描述
“ 寄 没 有 地 址 的 信 ,这 样 的 情 绪 有 种 距 离 ,你 放 着 谁 的 歌 曲 ,是 怎 样 的 心 情 。 能 不 能 说 给 我 听 。”
失忆的 Eden 总想努力地回忆起过去,然而总是只能清晰地记得那种思念的 感觉,却不能回忆起她的音容笑貌。
记忆中,她总是喜欢给 Eden 出谜题:在 valentine’s day 的夜晚,两人在闹市 中闲逛时,望着礼品店里精巧玲珑的各式玩偶,她突发奇想,问了 Eden 这样的 一个问题:有 n 个玩偶,每个玩偶有对应的价值、价钱,每个玩偶都可以被买有 限次,在携带的价钱 m 固定的情况下,如何选择买哪些玩偶以及每个玩偶买多 少个,才能使得选择的玩偶总价钱不超过 m,且价值和最大。
众所周知的,这是一个很经典的多重背包问题,Eden 很快解决了,不过她似 乎因为自己的问题被飞快解决感到了一丝不高兴,于是她希望把问题加难:多次 询问,每次询问都将给出新的总价钱,并且会去掉某个玩偶(即这个玩偶不能被 选择),再问此时的多重背包的答案(即前一段所叙述的问题)。
这下 Eden 犯难了,不过 Eden 不希望自己被难住,你能帮帮他么?
输入输出格式
输入格式:
从文件 bag.in 看读入数据。 第一行一个数 n,表示有 n 个玩偶,玩偶从 0 开始编号
第二行开始后面的 n 行,每行三个数 ai, bi, ci,分别表示买一个第 i 个玩偶需 要的价钱,获得的价值以及第 i 个玩偶的限购次数。
接下来的一行为 q,表示询问次数。
接下来 q 行,每行两个数 di, ei 表示每个询问去掉的是哪个玩偶(注意玩偶 从 0 开始编号)以及该询问对应的新的总价钱数。(去掉操作不保留,即不同询 问互相独立)
输出格式:
输出到文件 bag.out 中。 输出 q 行,第 i 行输出对于第 i 个询问的答案。
输入输出样例
输入样例#1: 复制
5
2 3 4
1 2 1
4 1 2
2 1 1
3 2 3
5
1 10
2 7
3 4
4 8
0 5
输出样例#1: 复制
13
11
6
12
4
说明
【样例说明】
一共五种玩偶,分别的价钱价值和限购次数为(2,3,4), (1,2,1), (4,1,2), (2,1,1), (3,2,3)。
五个询问,以第一个询问为例。
第一个询问表示的是去掉编号为 1 的玩偶, 且拥有的钱数为 10 时可以获得的最大价值,则此时剩余玩偶为(2,3,4),(4,1,2), (2,1,1),(3,2,3),若把编号为 0 的玩偶买 4 个(即全买了),然后编号为 3 的玩偶 买一个,则刚好把 10 元全部花完,且总价值为 13。可以证明没有更优的方案了。
注意买某种玩偶不一定要买光。
【数据范围】
10%数据满足 1 ≤ n ≤ 10;
另 20%数据满足 1 ≤ n ≤ 100, ci = 1, 1 ≤ q ≤ 100;
另 20%数据满足 1 ≤ n ≤ 100, 1 ≤ q ≤ 100;
另 30%数据满足 ci = 1;
100%数据满足 1 ≤ n ≤ 1000, 1 ≤ q ≤ 3*105, 1 ≤ ai、bi、ci ≤ 100, 0 ≤ di < n, 0 ≤ ei ≤ 1000。
解题思路
多组背包,正着跑一遍,反着跑一遍,然后对于每个询问O(m)合并。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
const int MAXN = 1005;
inline int rd(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
int a[MAXN],b[MAXN],c[MAXN];
int aa[MAXN],bb[MAXN],cc[MAXN];
int f[MAXN][MAXN],g[MAXN][MAXN];
int n,q,ans;
int main(){
n=rd();
for(register int i=1;i<=n;i++)
a[i]=rd(),b[i]=rd(),c[i]=rd();
for(register int i=1;i<=n;i++)
for(register int j=0;j<=1000;j++)
for(register int k=0;k<=c[i];k++){
if(k*a[i]<=j) f[i][j]=max(f[i][j],f[i-1][j-a[i]*k]+b[i]*k);
else break;
}
for(register int i=n;i;i--)
for(register int j=0;j<=1000;j++)
for(register int k=0;k<=c[i];k++){
if(k*a[i]<=j) g[i][j]=max(g[i][j],g[i+1][j-a[i]*k]+b[i]*k);
else break;
}
q=rd();
while(q--){
int x=rd(),y=rd();x++;
int ans=0;
for(register int i=0;i<=y;i++)
ans=max(ans,f[x-1][i]+g[x+1][y-i]);
printf("%d\n",ans);
}
return 0;
}
LUOGU P4095 [HEOI2013]Eden 的新背包问题的更多相关文章
- luogu P4095 [HEOI2013]Eden 的新背包问题 多重背包 背包的合并
LINK:Eden 的新背包问题 就是一个多重背包 每次去掉一个物品 询问钱数为w所能买到的最大值. 可以对于每次Q暴力dp 利用单调队列优化多重背包 这样复杂度是Qnm的. 发现过不了n==10的点 ...
- Luogu P4095 [HEOI2013]Eden 的新背包问题 思维/动规
当时一直在想前缀和...多亏张队提醒... 从1到n背次包,保存每一个状态下的价值,就是不要把第一维压掉:再从n到1背一次,同样记住每种状态: 然后询问时相当于是max(前缀+后缀),当然前缀后缀中间 ...
- Luogu P4095 [HEOI2013]Eden的新背包问题
题目 求出从前往后的背包\(f_{i,j}\)和从后往前的背包\(F_{i,j}\). 那么对于询问\((d,e)\),答案就是\(\max\limits_{i=0}^e f_{d-1,i}+F_{d ...
- P4095 [HEOI2013]Eden 的新背包问题
P4095 [HEOI2013]Eden 的新背包问题 题解 既然假定第 i 个物品不可以选,那么我们就设置两个数组 dpl[][] 正序选前i个物品,dpr[][] 倒序选前i个物品 ,价格不超过 ...
- 题解——洛谷P4095 [HEOI2013]Eden 的新背包问题(背包)
思路很妙的背包 用了一些前缀和的思想 去掉了一个物品,我们可以从前i-1个和后i+1个推出答案 奇妙的思路 #include <cstdio> #include <algorithm ...
- BZOJ 3163: [Heoi2013]Eden的新背包问题( 背包dp )
从左到右, 从右到左分别dp一次, 然后就可以回答询问了. ---------------------------------------------------------- #include< ...
- BZOJ3163&Codevs1886: [Heoi2013]Eden的新背包问题[分治优化dp]
3163: [Heoi2013]Eden的新背包问题 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 428 Solved: 277[Submit][ ...
- 洛谷P4095||bzoj3163 [HEOI2013]Eden 的新背包问题
https://www.luogu.org/problemnew/show/P4095 不太会.. 网上有神奇的做法: 第一种其实是暴力(复杂度3e8...)然而可以A.考虑多重背包,发现没有办法快速 ...
- bzoj 3163: [Heoi2013]Eden的新背包问题
Description "寄没有地址的信,这样的情绪有种距离,你放着谁的歌曲,是怎样的心心静,能不能说给我听."失忆的Eden总想努力地回忆起过去,然而总是只能清晰地记得那种思念的 ...
随机推荐
- java_缓冲流(字符输出流)
/** 字符缓冲流: * java.io.BufferedWriter extends writer * BufferedWriter:字符缓冲输出流: * * 构造方法: * BufferedWri ...
- P3480 [POI2009]KAM-Pebbles
P3480 [POI2009]KAM-Pebbles比如第一个样例 原:0 2 2差: 2 0 0如果把中间的2拿掉一个,就会变成原:0 1 2差: 1 1 0就可以把差看成阶梯nim细节:最终要移到 ...
- AutoIt自动化编程(4)【转】
五.自动化操作轻松入门系列5 控件操作 然而,在真正实现自动化时仅靠上面的技术往往难以达到预期目的.下面开始进入最为重要的控件操作. 1.设置文本 在安装软件的过程中用户往往需要提供一些必需信息,比如 ...
- ArrayList去除重复元素(多种方法实现)
package other; import java.util.ArrayList; import java.util.HashSet; public class test4 { public sta ...
- 二分图——最小覆盖poj2226
详见进阶指南 #include<iostream> #include<cstring> #include<cstdio> using namespace std; ...
- 简单DP (Preparing for Xtreme 12.0) | STL map使用
当水题遇上了map大坑 晚上写一个dp,弄了半天样例一直不过,对着队友的代码一行行看,发现跟自己逻辑完全一样啊... 然后就逐行输出比对,发现预处理出了问题,把map插入新值的地方改了下,果然就好了. ...
- mtk 的conferrence call建立流程
(重点看main_log与) 抓mtk log: 1.*#*#82533284#*#* 进入抓log UI 2.*#*#825364#*#* 进入工程模式 3.进入"Lo ...
- java线程池的使用学习
目录 1. 线程池的创建 2. 线程池的运行规则 3. 线程池的关闭 4. 线程池的使用场合 5. 线程池大小的设置 6 实现举例 1. 线程池的创建 线程池的创建使用ThreadPoolExecut ...
- 服务器IP配置功能实现小结
1. 服务器网卡配置文件 /etc/sysconfig/network/ifcfg-***(eth0) linux-f1s9:/etc/sysconfig/network # cat ifcfg-et ...
- java主函数参数传递args
a.javaJava应用程序的主入口方法main(String[] args),表示该方法需要接收一个字符串数组类型的参数, 如果该参数不指定,agrs接收的是null. 程序: public C ...