3163: [Heoi2013]Eden的新背包问题
Description
“寄没有地址的信,这样的情绪有种距离,你放着谁的歌曲,是怎样的心心静,能不能说给我听。”
失忆的Eden总想努力地回忆起过去,然而总是只能清晰地记得那种思念的感觉,却不能回忆起她的音容笑貌。 记忆中,她总是喜欢给Eden出谜题:在 valentine’s day 的夜晚,两人在闹市中闲逛时,望着礼品店里精巧玲珑的各式玩偶,她突发奇想,问了 Eden这样的一个问题:有n个玩偶,每个玩偶有对应的价值、价钱,每个玩偶都可以被买有限次,在携带的价钱m固定的情况下,如何选择买哪些玩偶以及每个玩偶买多少个,才能使得选择的玩偶总价钱不超过m,且价值和最大。众所周知的,这是一个很经典的多重背包问题,Eden很快解决了,不过她似乎因为自己的问题被飞快解决感到了一丝不高兴,于是她希望把问题加难:多次 询问,每次询问都将给出新的总价钱,并且会去掉某个玩偶(即这个玩偶不能被选择),再问此时的多重背包的答案(即前一段所叙述的问题)。
这下Eden 犯难了,不过Eden不希望自己被难住,你能帮帮他么?
Input
第一行一个数n,表示有n个玩偶,玩偶从0开始编号
第二行开始后面的 n行,每行三个数 ai, bi, c i,分别表示买一个第i个玩偶需
要的价钱,获得的价值以及第i个玩偶的限购次数。
接下来的一行为q,表示询问次数。
接下来q行,每行两个数di. ei表示每个询问去掉的是哪个玩偶(注意玩偶从0开始编号)以及该询问对应的新的总价钱数。(去掉操作不保留,即不同询问互相独立)
Output
输出q行,第i行输出对于第 i个询问的答案。
Sample Input
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
Sample Output
11
6
12
4
HINT
一共五种玩偶,分别的价钱价值和限购次数为 (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。可以证明没有更优的方案了。注意买某种玩偶不一定要买光。 数据满足1 ≤ n ≤ 1000, 1 ≤ q ≤ 3*10的5次方 , 1 ≤ ai、bi、c i ≤ 100, 0 ≤ d i < n, 0 ≤ei ≤ 1000。
x-1,x+1——n中取最优解,我们把它分成两半,分配左边一定数目的钱,分配右边一定数目的钱,由于之前做过完全背包,我们可以直接得出左边和右边在一定钱数下的最优解,
相加后即为一种可能的答案,当然我们需要枚举分配的钱数在不同的可能性之间进行比较才能达到最终答案。
我采用了二进制优化来避免超限。
ps:这个程序时间复杂度在最后有可能达到O(3*10^8),但是数据水,所以过去了,还是建议看那些大神的题解。
具体看程序:
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cstdio>
using namespace std;
int n,t,x,y,z,maxm,now,ans,q,d[],e[],w[],v[],l[],r[],f[][],f2[][];
int max(int a,int b)
{
return (a>b?a:b);
}
int main()
{
scanf("%d",&n);
now=;
for (int i=;i<=n;i++)
{
t=;
l[i]=now;//记录这种物品被分开后在背包中开始的位置
scanf("%d %d %d",&x,&y,&z);
while ((t*-)<z)//转换为01背包,并且进行二进制优化
{
w[now]=t*x;
v[now]=t*y;
t*=;
now+=;
}
w[now]=(z-t+)*x;
v[now]=(z-t+)*y;
r[i]=now;//记录这种物品被分开后在背包中最后的位置
now+=;
}
scanf("%d",&q);
for (int i=;i<=q;i++)
{
scanf("%d %d",&d[i],&e[i]);
d[i]+=;
if (e[i]>maxm) maxm=e[i];//所有钱数中的最大值
}
for (int i=;i<=now;i++)//正着做01背包
for (int j=maxm;j>=;j--)
if (j-w[i]>=) f[i][j]=max(f[i-][j],f[i-][j-w[i]]+v[i]);
else f[i][j]=f[i-][j];
for (int i=;i<=now/;i++)//把背包倒过来
{
t=w[i]; w[i]=w[now-i+];w[now-i+]=t;
t=v[i]; v[i]=v[now-i+];v[now-i+]=t;
}
for (int i=;i<=now;i++)//倒着做01背包
for (int j=maxm;j>=;j--)
if (j-w[i]>=) f2[i][j]=max(f2[i-][j],f2[i-][j-w[i]]+v[i]);
else f2[i][j]=f2[i-][j];
for (int i=;i<=q;i++)//开始回答问题
{
ans=;
for (int j=;j<=e[i];j++)//枚举分配给左边多少钱
ans=max(ans,f[l[d[i]]-][j]+f2[now-r[d[i]]][e[i]-j]);
//这个可以去推一下l[d[i]]-1表示被删物品的前一个物品在f背包中的结束位置,now-r[d[i]]表示被删物品的后一个物品在f2背包中的开始位置。
printf("%d\n",ans);
}
return ;
}
好啦
3163: [Heoi2013]Eden的新背包问题的更多相关文章
- BZOJ 3163: [Heoi2013]Eden的新背包问题( 背包dp )
从左到右, 从右到左分别dp一次, 然后就可以回答询问了. ---------------------------------------------------------- #include< ...
- bzoj 3163: [Heoi2013]Eden的新背包问题
Description "寄没有地址的信,这样的情绪有种距离,你放着谁的歌曲,是怎样的心心静,能不能说给我听."失忆的Eden总想努力地回忆起过去,然而总是只能清晰地记得那种思念的 ...
- BZOJ3163&Codevs1886: [Heoi2013]Eden的新背包问题[分治优化dp]
3163: [Heoi2013]Eden的新背包问题 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 428 Solved: 277[Submit][ ...
- P4095 [HEOI2013]Eden 的新背包问题
P4095 [HEOI2013]Eden 的新背包问题 题解 既然假定第 i 个物品不可以选,那么我们就设置两个数组 dpl[][] 正序选前i个物品,dpr[][] 倒序选前i个物品 ,价格不超过 ...
- luogu P4095 [HEOI2013]Eden 的新背包问题 多重背包 背包的合并
LINK:Eden 的新背包问题 就是一个多重背包 每次去掉一个物品 询问钱数为w所能买到的最大值. 可以对于每次Q暴力dp 利用单调队列优化多重背包 这样复杂度是Qnm的. 发现过不了n==10的点 ...
- bzoj3163: [Heoi2013]Eden的新背包问题
Description “寄没有地址的信,这样的情绪有种距离,你放着谁的歌曲,是怎样的心心静,能不能说给我听.”失忆的Eden总想努力地回忆起过去,然而总是只能清晰地记得那种思念的感觉,却不能回忆起她 ...
- LUOGU P4095 [HEOI2013]Eden 的新背包问题
题目描述 " 寄 没 有 地 址 的 信 ,这 样 的 情 绪 有 种 距 离 ,你 放 着 谁 的 歌 曲 ,是 怎 样 的 心 情 . 能 不 能 说 给 我 听 ." 失忆的 ...
- 题解——洛谷P4095 [HEOI2013]Eden 的新背包问题(背包)
思路很妙的背包 用了一些前缀和的思想 去掉了一个物品,我们可以从前i-1个和后i+1个推出答案 奇妙的思路 #include <cstdio> #include <algorithm ...
- Luogu P4095 [HEOI2013]Eden 的新背包问题 思维/动规
当时一直在想前缀和...多亏张队提醒... 从1到n背次包,保存每一个状态下的价值,就是不要把第一维压掉:再从n到1背一次,同样记住每种状态: 然后询问时相当于是max(前缀+后缀),当然前缀后缀中间 ...
随机推荐
- Linux 下没有conio.h 已解决
原文:http://blog.sina.com.cn/s/blog_6a95e00b0100zqvf.html #include <stdio.h>//#include <conio ...
- 新的android studio创建的fragment工程跟老师讲的结构有区别
工程自动创建了fragment类,并且activity_main中的标签是fragmnet,这就不需要在MainAcitivity中手动创建fragment了. 但是这样的程序运行之后会出现两个fra ...
- 通过DOM节点操作来获取表单信息
这是之前突发奇想地用dom节点的关系来操作表单的故事.. 事情的经过是这样的,大概就是一个平台注册后有留言功能,管理员登录之后可以对这些留言进行回复.这个页面呢,就是通过foreach获取到数据库里的 ...
- 【caffe-windows】 caffe-master 之 matlab接口配置
平台环境: win10 64位 caffe-master vs2013 Matlab2016a 第一步: 打开\caffe-master\windows下的CommonSettings.props文 ...
- oracle分配权限:一个用户访问另一个用户的表
相当于alias(别名),比如把user1.table1在user2中建一个同义词table1 create synonym table1 for user1.table1; 这样当你在user2中查 ...
- PHP超时处理全面总结
[ 概述 ] 在PHP开发中工作里非常多使用到超时处理到超时的场合,我说几个场景: 1. 异步获取数据如果某个后端数据源获取不成功则跳过,不影响整个页面展现 2. 为了保证Web服务器不会因为当个页面 ...
- MyEclipse+Tomcat 启动时出现A configuration error occured during startup错误的解决方法
MyEclipse+Tomcat 启动时出现A configuration error occured during startup错误的解决方法 分类: javaweb2013-06-03 14:4 ...
- position:absolute和float会隐式的改变display类型
position:absolute和float会隐式的改变display类型,不论之前是什么类型的元素(display:none除外),只要设置了position:absolute或float,都会让 ...
- CSS3 中的 rem 值与 px 之间的换算
想给博客换个主题,到处找找不到满意的,最后发现默认主题 twentytwelve 越看越顺眼,于是就想动手改一下用. 看 CSS 文件的时候发现引入了一个新大小单位:rem,虽然 CSS 文件注释里有 ...
- Java多线程断点下载
public static class DownloadThread extends Thread{ private int threadId; private int startIndex; pri ...