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

很好理解,第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. C++中stl的map

    总结: 在map中插入数据有三种方法: 1.用insert插入pair数据: mapstudent.insert(pair<int,string>(1,"studentone&q ...

  2. 在centos7上安装elasticSearch

    因为elasticsearch是用java编写的,所以需要先安装JDK: jdk1.8的安装:安装指导 elasticsearch的下载和安装 一.下载elasticSearch 1.下载地址: ht ...

  3. 八皇后问题(dfs)

    #include <iostream> #include <stdio.h> using namespace std; ; ], b[], c[], vis[][]; //a, ...

  4. win10安装.net3.5

    近日有网友反映在windows10_64位系统电脑上安装Net framework3.5,操作时总失败,怎么办呢?小编下面就介绍win10 64位系统无法安装Net framework3.5的两种解决 ...

  5. Go语言之讲解GOROOT、GOPATH、GOBIN

    Go是一门全新的静态类型开发语言,具有自动垃圾回收,丰富的内置类型,函数多返回值,错误处理,匿名函数,并发编程,反射等特性. go命令依赖一个重要的环境变量:$GOPATH GOPATH允许多个目录, ...

  6. win32多线程程序设计

    标题是一本书名,写得挺有意思的,是今天早上同事带过来的,我借过来看了一会儿. 然后按照书里面前面几章的内容敲了一些代码,跑了几个例子看了一下. 创建线程的函数: HANDLE CreateThread ...

  7. CF402D Upgrading Array

    原题链接 先用素数筛筛下素数,然后考虑贪心去操作. 先求前缀\(GCD\)(求到\(GCD\)为\(1\)就不用再往下求了),得到数组\(G[i]\),然后从后往前扫,如果\(f(G[i]) < ...

  8. AppStore企业账号打包发布APP流程详解

    一.通过企业账号申请证书 1 Certificate Signing Request (CSR)文件 在Mac系统中进入“钥匙串访问”,选择“钥匙串访问”-“证书助理”-“从证书颁发机构请求证书…”, ...

  9. websocket activemq

    websocket:应用与服务端保持长连接 不停通信 activemq:偶发通信  心跳机制

  10. oracle 笔记DBA

    1.1oracle开启归档 关闭数据库 SQL>archive log list; SQL>shutdown immediate; SQL>startup mount ; SQL&g ...