其实这个问题,真的挺好想的,但是我咋想了那么久呢~~

很好理解,第K大01背包一定基于01背包,dp数组也很容易的想到由dp[V]  ---->   dp[V][K],来表示背包容量是V时候的第K大背包

然后就是状态转移方程了,多写一写,你也能手推出来的,不能被吓到

dp[V][1] = max_第一大(dp[v][1],dp[v-w][1]+vi)

dp[V][2] = max_第二大数(dp[v][1],dp[v-w][1]+vi,dp[v][2],dp[v-w][2]+vi) =  max_第二大数(dp[v][1],dp[v][2],dp[v-w][2]+vi)

从而得到一般式子

dp[v][k] = max_第K大(dp[v][1],dp[v][2],....dp[v][k],dp[v-w][1]+vi,.....dp[v-w][k]+vi

明白了这两个,代码方面就比较好实现了

可以用排序来进行

但是一看排列,发现取第K大值分为两部分,且排列都是降序,所以我们可以用两个数组存储起来,然后进行赋值(复杂度也比较低)

/*
dp[x][y]表示的是容量为x的第k大值
所以dp[x][1] = max_(第一大值){dp[x][1],dp[x-v][1]+w}
dp[x][2] = max_(第二大值){dp[x][1],dp[x][2],dp[x-v][1]+w,dp[x-v][2]+w}
依次类推~~
*/
/*
因为dp[j][1]...dp[j][k]与dp[j-w[i]][1]+v[i]...dp[j-w[i]][k]+v[i]
是依次递减的,那么我们可以用两个数组将这两组数组保存起来,
再O(N)的时间内求得第K大。
*/
#include <iostream>
#include <cstdio>
#include <string.h>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn = 1005;
int dp[maxn][maxn];
int n,W,K;//W:总容量值,K第K大值
int v[maxn],w[maxn];//价值,一个为体积
int s1[maxn],s2[maxn];
void KthZeroOnePack()
{
for(int i = 0;i < n;i++)//遍历了每一个物品
{
for(int j = W;j >= w[i];j--)//层铺每一层体积
{
for(int th = 1;th <= K;th++)//求取前k大值
{
//0 - k-1 到K结束
s1[th-1] = dp[j][th];//遍历存储每一个可能取到的值,且s1是递减的
s2[th-1] = dp[j - w[i]][th] + v[i];//遍历存储每一个可能取到的值,且s2是递减的
}
//特判结束点
s1[K] = s2[K] = -1;
int cnt = 1,cnt1 = 0,cnt2 = 0;
//从第一大开始
while(cnt <= K && (s1[cnt1] != -1 || s2[cnt2] != -1))
{
if(s1[cnt1] > s2[cnt2])dp[j][cnt] = s1[cnt1++];
else dp[j][cnt] = s2[cnt2++];
//严格递减
if(dp[j][cnt] != dp[j][cnt-1]) cnt++;
} }
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&n,&W,&K);
memset(dp,0,sizeof(dp));
for(int i = 0;i < n;i++)
{
scanf("%d",&v[i]);
}
for(int i = 0;i < n;i++)
{
scanf("%d",&w[i]);
}
KthZeroOnePack();
printf("%d\n",dp[W][K]);
}
return 0;
}

第K大01背包的更多相关文章

  1. hdu 2639 第k大01背包

    求每个状态里的k优解,然后合并 /* HDU 2639 求01背包的第k大解. 合并两个有序序列 */ #include<stdio.h> #include<iostream> ...

  2. [HDOJ2639]Bone Collector II(第k优01背包)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2639 题意:求01背包的第k优解 dp(i, j)表示容量为j时的i优解 对于第二维的操作和01背包几 ...

  3. hdu1864 最大报销额(01背包)

    转载请注明出处:http://blog.csdn.net/u012860063 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1864 Problem ...

  4. HDU 2639 Bone Collector II(01背包变形【第K大最优解】)

    Bone Collector II Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  5. HDU 2639(01背包求第K大值)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2639 Bone Collector II Time Limit: 5000/2000 MS (Jav ...

  6. HDU 2639 01背包求第k大

    Bone Collector II Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  7. HDU 2639 Bone Collector II【01背包 + 第K大价值】

    The title of this problem is familiar,isn't it?yeah,if you had took part in the "Rookie Cup&quo ...

  8. HDU2639(01背包第K大)

    Bone Collector II Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  9. hdu 2639 Bone Collector II(01背包 第K大价值)

    Bone Collector II Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

随机推荐

  1. Luogu 2822[NOIP2016] 组合数问题 - 数论

    题解 乱搞就能过了. 首先我们考虑如何快速判断C(i, j ) | k 是否成立. 由于$k$非常小, 所以可以对$k$分解质因数, 接着预处理出前N个数的阶乘的因数中 $p_i$ 的个数, 然后就可 ...

  2. MS-Office使用技巧

    1.角标设置 下角标:选中(Shift+左右方向键)-->Ctrl+= 上角标:选中(Shift+左右方向键)-->Ctrl+Shift+=(Ctrl++) 撤销:同样操作 2.MS Of ...

  3. Python之路(第十一篇)装饰器

    一.什么是装饰器? 装饰器他人的器具,本身可以是任意可调用对象,被装饰者也可以是任意可调用对象. 强调装饰器的原则:1 不修改被装饰对象的源代码 2 不修改被装饰对象的调用方式 装饰器的目标:在遵循1 ...

  4. ListView item中有button或EditText时 点击事件失效问题的解决

    加入:android:descendantFocusability="blocksDescendants" 代码如下: <LinearLayout xmlns:android ...

  5. 将hibernate框架融入到spring框架中

    第一步:首先创建表: create table  user( id int(2) primary key,name varchar(20),password varchar(20)); 第二步:建立d ...

  6. ios 内存管理与property copy strong weak assign

    - (void)fun{  NSString* str = [[NSString alloc] initWithString:@"string"];  NSLog(@"% ...

  7. 几张图片帮助记忆docker基本原理(转)

    写的非常好的一篇文章,不知道为什么被删除了. 利用Google快照,做个存档. 快照地址:地址 作者地址:青牛 什么是dockerDocker 是一个开源项目,诞生于 2013 年初,最初是 dotC ...

  8. 论Java的重要性

    最近,最新的世界编程语言排名最近出炉了,Java位居世界第一.          不仅如此,Java以17.856%超过第二名C语言的8.726%两倍以上,其实,这一现象是十分反常的,因为,在前几年, ...

  9. MySQL查找SQL耗时瓶颈 SHOW profiles

    http://blog.csdn.net/k_scott/article/details/8804384 1.首先查看是否开启profiling功能 SHOW VARIABLES LIKE '%pro ...

  10. django之http

    一 http协议介绍 http协议(Hyper Text Transfer Protocol):超文本传输协议,是基于应用层的面向对象协议,靠tcp协议和IP来传输数据,请求和响应是http协议的基本 ...