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

很好理解,第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. 前端面试问题html汇总

    1.对WEB标准以及W3C的理解与认识 结构层 html :表示层  css:行为层:js; 标签闭合.标签小写.不乱嵌套.提高搜索机器人搜索机率.使用外链css和js脚本.结构行为表现的分离.文件下 ...

  2. 洛谷4782 【模板】2-SAT 问题

    原题链接 \(2-SAT\)模板 #include<cstdio> using namespace std; const int N = 2e6 + 10; int fi[N], di[N ...

  3. Window7安装tensorflow整套环境详细流程

    安装tensorflow方式有好多种,为了方便编译环境以及包管理,这里采用Anaconda平台安装tensorflow. tensorflow官网:http://www.tensorflow.org/ ...

  4. Netty 源码 ChannelHandler(三)概述

    Netty 源码 ChannelHandler(三)概述 Netty 系列目录(https://www.cnblogs.com/binarylei/p/10117436.html) 一.Channel ...

  5. 下载win10

    http://www.xitongtiandi.net/win10yuanban/2039.html#download

  6. eclipse安装提要

    svn 插件安装http://subclipse.tigris.org/update_1.12.x教程地址http://jingyan.baidu.com/article/f71d60376b4c57 ...

  7. Python sys.argv[] 的用法

    sys.argv变量是一个list, 执行 python abc.py a b c 时, sys.argv[0]为 abc.py sys.argv[1]为 a sys.argv[2]为 b sys.a ...

  8. 2018.10.27 loj#2292. 「THUSC 2016」成绩单(区间dp)

    传送门 g[i][j][k][l]g[i][j][k][l]g[i][j][k][l]表示将区间l,rl,rl,r变成最小值等于kkk,最大值等于lll时的花费的最优值. f[i][j]f[i][j] ...

  9. java equals重写

    @Override    public boolean equals(Object obj) {        if(this == obj) {            return true;   ...

  10. jquery checkbox反复调用attr('checked', true/false)只有第一次生效 Jquery 中 $('obj').attr('checked',true)失效的几种解决方案

    1.$('obj').prop('checked',true) 2. $(':checkbox').each(function(){ this.checked=true; }) 为什么:attr为失效 ...