题目描述

“ 寄 没 有 地 址 的 信 ,这 样 的 情 绪 有 种 距 离 ,你 放 着 谁 的 歌 曲 ,是 怎 样 的 心 情 。 能 不 能 说 给 我 听 。”

失忆的 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 的新背包问题的更多相关文章

  1. luogu P4095 [HEOI2013]Eden 的新背包问题 多重背包 背包的合并

    LINK:Eden 的新背包问题 就是一个多重背包 每次去掉一个物品 询问钱数为w所能买到的最大值. 可以对于每次Q暴力dp 利用单调队列优化多重背包 这样复杂度是Qnm的. 发现过不了n==10的点 ...

  2. Luogu P4095 [HEOI2013]Eden 的新背包问题 思维/动规

    当时一直在想前缀和...多亏张队提醒... 从1到n背次包,保存每一个状态下的价值,就是不要把第一维压掉:再从n到1背一次,同样记住每种状态: 然后询问时相当于是max(前缀+后缀),当然前缀后缀中间 ...

  3. Luogu P4095 [HEOI2013]Eden的新背包问题

    题目 求出从前往后的背包\(f_{i,j}\)和从后往前的背包\(F_{i,j}\). 那么对于询问\((d,e)\),答案就是\(\max\limits_{i=0}^e f_{d-1,i}+F_{d ...

  4. P4095 [HEOI2013]Eden 的新背包问题

    P4095 [HEOI2013]Eden 的新背包问题 题解 既然假定第 i 个物品不可以选,那么我们就设置两个数组 dpl[][] 正序选前i个物品,dpr[][] 倒序选前i个物品 ,价格不超过 ...

  5. 题解——洛谷P4095 [HEOI2013]Eden 的新背包问题(背包)

    思路很妙的背包 用了一些前缀和的思想 去掉了一个物品,我们可以从前i-1个和后i+1个推出答案 奇妙的思路 #include <cstdio> #include <algorithm ...

  6. BZOJ 3163: [Heoi2013]Eden的新背包问题( 背包dp )

    从左到右, 从右到左分别dp一次, 然后就可以回答询问了. ---------------------------------------------------------- #include< ...

  7. BZOJ3163&Codevs1886: [Heoi2013]Eden的新背包问题[分治优化dp]

    3163: [Heoi2013]Eden的新背包问题 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 428  Solved: 277[Submit][ ...

  8. 洛谷P4095||bzoj3163 [HEOI2013]Eden 的新背包问题

    https://www.luogu.org/problemnew/show/P4095 不太会.. 网上有神奇的做法: 第一种其实是暴力(复杂度3e8...)然而可以A.考虑多重背包,发现没有办法快速 ...

  9. bzoj 3163: [Heoi2013]Eden的新背包问题

    Description "寄没有地址的信,这样的情绪有种距离,你放着谁的歌曲,是怎样的心心静,能不能说给我听."失忆的Eden总想努力地回忆起过去,然而总是只能清晰地记得那种思念的 ...

随机推荐

  1. java空和非空判断

    public static boolean isEmpty(String str){ if("".equals(str)||str==null){ return true; }el ...

  2. 2018-8-10-如何删除错误提交的-git-大文件

    title author date CreateTime categories 如何删除错误提交的 git 大文件 lindexi 2018-08-10 19:16:51 +0800 2018-2-1 ...

  3. UMP系统功能 资源隔离

  4. thinkphp3.2.3 nginx 连接mysql 报错 new PDO 异常

    在 php.ini 里重新指定mysql.sock 路径 pdo_mysql.default_socket=/Applications/XAMPP/xamppfiles/var/mysql/mysql ...

  5. Android开发 BottomNavigationView学习

    前言 注意这个里介绍的是AndroidX的com.google.android.material.bottomnavigation.BottomNavigationView xml布局中 <co ...

  6. thinkphp 命名范围

    在应用开发过程中,使用最多的操作还是数据查询操作,凭借ThinkPHP的连贯操作的特性,可以使得查询操作变得更优雅和清晰,命名范围功能则是给模型操作定义了一系列的封装,让你更方便的操作数据. 命名范围 ...

  7. 「BZOJ2391」Cirno的忧郁

    传送门 设p[0] = (-10001,-10001) 把所有点按p[0]极角排序, s[i][j]表示三角形p[0]p[i]p[j]内的总价值,若i到j极角增大则s为正,否则s为负. 那么答案就是按 ...

  8. js摇一摇事件

    今早同事过来说.要做个小游戏.里面有个摇一摇动作. 平时都是做的手机营销h5比较少.  发现很有意思.  一时间没有反应过来. 怎么实现的摇一摇. 现在吧代码叠出来给2货的我. //运动事件监听if ...

  9. RESTful API -- rules

    RESTful介绍 REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移”或“表现层状态转化”. 推荐 ...

  10. Java(8)中List的遍历方式总结

    本篇文章主要讲述了List这一集合类型在Java,包括Java8中的遍历方式,不包括其他的过滤,筛选等操作,这些操作将会在以后的文章中得到提现,由List可以类推到Set等类似集合的遍历方式. pub ...