背包的第k优解问题
来源:互联网 发布:淘宝怎么卖话费 编辑:程序博客网 时间:2024/05/29 17:33
nkoj 2347
Description
Lynn 和banana要去爬山啦!他们一共有 K 个人(banana的人数可以看作很多),每个人都会背一个包。这些包的容量是相同的,都是 V。可以装进背包里的一共有 N 种物品,每种物品都有给定的体积和价值。在 lynn看来,合理的背包安排方案是这样的:
(1)每个人背包里装的物品的总体积恰等于包的容量。
(2)每个包里的每种物品最多只有一件,但两个不同的包中可以存在相同的物品。
(3)任意两个人,他们包里的物品清单不能完全相同。
在满足以上要求的前提下,所有包里的所有物品的总价值最大是多少呢?
Input
第一行有三个整数:K、V、N。(k<=50 v<=5000 n<=200)第二行开始的 N 行,每行有两个整数,分别代表这件物品的体积和价值。
Output
只需输出一个整数,即在满足以上要求的前提下所有物品的总价值的最大值。(最后有空行.)
Sample Input
2 10 53 127 202 45 61 1
Sample Output
57
分析:
问题其实就是要求背包问题的前k个最优解
设 f[j][p] 表示体积为 j 时的第 p 优解,一定是单调递减的队列。
对于第i个物品:
新队列 y=f[j-v[i]][p]+w[i] 一定也是单调递减的。
那么问题就变成了从两个k个元素的单调队列中选出前k个较大的。
代码如下:
#include<cstdio>#include<iostream>using namespace std;int n,v,k,s[205],w[205],f[5005][205],x[55],y[55];//x、y就是用来缓冲的队列; int main(){int i,j,p,p2,p3;scanf("%d%d%d",&k,&v,&n);for(i=1;i<=n;i++)scanf("%d%d",&s[i],&w[i]);for(i=0;i<=v;i++)for(j=0;j<=k;j++) //一定要注意初值 f[i][j]=-100000000;f[0][1]=0;for(i=1;i<=n;i++)for(j=v;j>=s[i];j--){for(p=1;p<=k;p++)x[p]=f[j][p],y[p]=f[j-s[i]][p]+w[i];for(p=p2=p3=1;p<=k;p++){//p2、p3分别为x,y的队首指针; if(x[p2]>y[p3])f[j][p]=x[p2++];else f[j][p]=y[p3++];}}int ans=0; //累计答案 for(i=1;i<=k;i++)ans+=f[v][i];printf("%d",ans);}
0 0
- 背包的第k优解问题
- 背包问题中求次优解,第K优解的方法
- hdu 2639Bone Collector II 背包的第K优解问题
- 背包问题第k优解
- 背包问题第k优解
- 背包问题 ——第K优解 或 次优解
- vijos1412(第k优背包)
- vijos第k优背包
- hdu 2639 Bone Collector II (01背包,第k优解问题)
- hdu 2636 Bone Collector II 01背包(第k优解问题)
- hdu2639背包问题第K优解
- HDU 2639 第K大背包问题
- 背包问题求第K优解
- 背包问题--求第K大值
- hdu2639Bone Collector II(01背包的第k优策略)
- poj 2639 背包的第k最优解
- hdu 2639 【01背包的第k个最优解】
- hdu2639-01背包(第k大背包问题)
- Android_Fragment
- android基础学习综合实例——天气预报App(基本功能实现)
- fishhook
- BASE64加解密实现方法
- Android学习心得第一课
- 背包的第k优解问题
- iOS 开发 -- Swift 语法篇 (一) 常量和变量
- Memcached
- Cocos2d-x ListView 的添加,删除,点击和滑动到头和尾监听
- 信号量——POSIX 与 System V的接口对比分析
- vs2015 + BabeLua + Cocos2d-x 3.10配置
- 2016年阅读书单(一)
- 数据结构常用树的基本总结
- HDU 5630 Rikka with Chess