题目描述

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

失忆的 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开发系列-时间转换

    获取当前时间戳 // 获取当前的时间戳 long time = new Date().getTime(); 将字符串时间戳转成格式的时间字符串 Long timestrap = Long.parseL ...

  2. java 压缩包

    package com.gome.budget.common.utils; import org.apache.commons.compress.archivers.ArchiveEntry; imp ...

  3. 一个页面上调用多个setInterval失效解决办法(使用于同一时间间隔)

    将方法封装在一起,只调用一个setInterval window.setInterval( function () { $.ajax({ type: "GET", url: '/M ...

  4. localhost与127.0.0.1区别

    一.连接MySQL数据库有两种方式:TCP/IP(一般理解的端口的那种)和Unix套接字(一般叫socket或者sock) 大部分情况下,可以用localhost代表本机127.,但是在MySQL连接 ...

  5. JUC 一 Callable

    java.util.concurrent.Callable是一个泛型接口,只有一个call()方法 Callable和Runnable的区别 Callable使用call()方法,Runnable使用 ...

  6. MySQL其他和备份

    目录 事务 存储引擎 InnoDB存储引擎 数据存储形式 锁的粒度 事务 数据的存储特点 MyISAM存储引擎 数据存储形式 锁的粒度 事务 数据的存储特点 其他 对比与选择 视图 触发器 存储过程 ...

  7. 修改cmd命令默认路径

    未修改之前: 修改方法: 1.win+r打开运行对话框,输入 regedit 打开注册表编辑器 2.在注册表中找到:HKEY_CURRENT_USER\Software\Microsoft\Comma ...

  8. 项目接入即时聊天客服系统(环信系统)PHP后端操作

    环信工作原理: 一.由于环信没有直接的接口来主动调取本项目中的用户数据,所有用户信息必须在环信服务器上注册对应信息成为环信的用户:(这样才能当用户进入聊天时显示其基本信息,如:名称.昵称.电话.邮箱等 ...

  9. iOS开发UITableView的动画cell

    1.动画cell 针对cell的动画,在Delegate中对cell的layer进行操作: 2.实现代码 #import "ViewController.h" #import &q ...

  10. Cocos2d-x 创建工程python脚本

    @echo offset /p projectName=请输入项目名称:if "%projectName%"=="" goto inputErrorset /p ...