The title of this problem is familiar,isn't it?yeah,if you had took part in the "Rookie Cup" competition,you must have seem this title.If you haven't seen it before,it doesn't matter,I will give you a link:

Here is the link: http://acm.hdu.edu.cn/showproblem.php?pid=2602

Today we are not desiring the maximum value of bones,but the K-th maximum value of the bones.NOTICE that,we considerate two ways that get the same value of bones are the same.That means,it will be a strictly decreasing sequence from the 1st maximum , 2nd maximum .. to the K-th maximum.

If the total number of different values is less than K,just ouput 0.

Input

The first line contain a integer T , the number of cases.

Followed by T cases , each case three lines , the first line contain two integer N , V, K(N <= 100 , V <= 1000 , K <= 30)representing the number of bones and the volume of his bag and the K we need. And the second line contain N integers representing the value of each bone. The third line contain N integers representing the volume of each bone.

Output

One integer per line representing the K-th maximum of the total value (this number will be less than 2 31).

Sample Input

3

5 10 2

1 2 3 4 5

5 4 3 2 1

5 10 12

1 2 3 4 5

5 4 3 2 1

5 10 16

1 2 3 4 5

5 4 3 2 1

Sample Output

12

2

0

【题意】: 给定背包容量,骨头的个数和每个骨头的价值,这次不是求在背包容量允许的情况下,最多装的价值,而是求在背包容量内,可以装的第k大价值,如果没有第k个最大值,那么输出0。

【分析】:

求背包的第k大方案,只需在状态上加入一维dp[j][k]表示前i个物品装入容量为j的背包的第k大的方案,用两个数组辅助保存下装和不装两种选择下的前k大方案,再最后合并起来得到最终结果 。

要求的是第K个最大值,那么不用 dp[j]=max(dp[j],dp[j-w[i]]+v[i])的状态转移方程,而是将两个值都记录下来,用for循环走一遍,记录下,容量为1到M的各个最大价值,dp[i][j]表示当背包容量为i时的第j个最大价值,最后只需要输出dp[m][k]即可

【精彩讲解】:HDU2639 01背包 第K优决策

#include<cstdio>
#include<string>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<cstring>
#include<set>
#include<queue>
#include<algorithm>
#include<vector>
#include<map>
#include<cctype>
#include<stack>
#include<sstream>
#include<list>
#include<assert.h>
#include<bitset>
#include<numeric>
#define debug() puts("++++")
#define gcd(a,b) __gcd(a,b)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define fi first
#define se second
#define pb push_back
#define sqr(x) ((x)*(x))
#define ms(a,b) memset(a,b,sizeof(a))
#define sz size()
#define be begin()
#define pu push_up
#define pd push_down
#define cl clear()
#define lowbit(x) -x&x
#define all 1,n,1
#define rep(i,n,x) for(int i=(x); i<(n); i++)
#define in freopen("in.in","r",stdin)
#define out freopen("out.out","w",stdout)
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> P;
const int INF = 0x3f3f3f3f;
const LL LNF = 1e18;
const int maxn = 1e5 + 5;
const int maxm = 1e6 + 10;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int dx[] = {-1,1,0,0,1,1,-1,-1};
const int dy[] = {0,0,1,-1,1,-1,1,-1};
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
/*
总的复杂度是O(VNK)
3
5 10 2
1 2 3 4 5
5 4 3 2 1
5 10 12
1 2 3 4 5
5 4 3 2 1
5 10 16
1 2 3 4 5
5 4 3 2 1
*/
int n,m,K;
#define S 100000
#define M 200000
int w[1005],v[1005];
int a[1005],b[1005];
int dp[1005][1005];//设dp[j][k]为容量为j的背包所获得的第k大价值
int main()
{
int t;
cin>>t;
while(t--)
{
memset(dp,0,sizeof(dp));
memset(a,0,sizeof(a));
memset(b,0,sizeof(b)); cin>>n>>m>>K;
for(int i=1;i<=n;i++) cin>>v[i];
for(int i=1;i<=n;i++) cin>>w[i];
for(int i=1;i<=n;i++){
for(int j=m;j>=w[i];j--){
for(int k=1;k<=K;k++){ //用两个数组辅助保存下装和不装两种选择下的前k大方案
a[k] = dp[j][k];
b[k] = dp[j-w[i]][k] + v[i];
}
//a[K+1]=b[K+1]=-1;
int x=1,y=1,z=1;
while(z<=K && (x<=K||y<=K)){ //二路归并
if(a[x]>=b[y]) //不能去掉等于
dp[j][z]=a[x++];
else
dp[j][z]=b[y++];
if(dp[j][z-1] != dp[j][z]) z++; //去重
}
}
}
cout<<dp[m][K]<<endl;
}
return 0;
}

HDU 2639 Bone Collector II【01背包 + 第K大价值】的更多相关文章

  1. HDU - 2639 Bone Collector II (01背包第k大解)

    分析 \(dp[i][j][k]\)为枚举到前i个物品,容量为j的第k大解.则每一次状态转移都要对所有解进行排序选取前第k大的解.用两个数组\(vz1[],vz2[]\)分别记录所有的选择情况,并选择 ...

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

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

  3. HDU 2639 Bone Collector II(01背包变型)

    此题就是在01背包问题的基础上求所能获得的第K大的价值. 详细做法是加一维去推当前背包容量第0到K个价值,而这些价值则是由dp[j-w[ i ] ][0到k]和dp[ j ][0到k]得到的,事实上就 ...

  4. HDU 2639 Bone Collector II (01背包,第k解)

    题意: 数据是常规的01背包,但是求的不是最大容量限制下的最佳解,而是第k佳解. 思路: 有两种解法: 1)网上普遍用的O(V*K*N). 2)先用常规01背包的方法求出背包容量限制下能装的最大价值m ...

  5. hdu–2369 Bone Collector II(01背包变形题)

    题意:求解01背包价值的第K优解. 分析: 基本思想是将每个状态都表示成有序队列,将状态转移方程中的max/min转化成有序队列的合并. 首先看01背包求最优解的状态转移方程:\[dp\left[ j ...

  6. HDOJ(HDU).2602 Bone Collector (DP 01背包)

    HDOJ(HDU).2602 Bone Collector (DP 01背包) 题意分析 01背包的裸题 #include <iostream> #include <cstdio&g ...

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

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

  8. hdu 2639 Bone Collector II

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

  9. HDU 2639 Bone Collector II (dp)

    题目链接 Problem Description The title of this problem is familiar,isn't it?yeah,if you had took part in ...

随机推荐

  1. 关于safaire下hash前面需要加/(正斜杠)

    就是我们1.1框架是根据hash跳转的,今天我2.0跳转到1.1,pc一直测下来都是好的, 然后发现手机上一直跳转有问题,然后排查了半小时左右才发现  hash前面需要加/ 分割. 例如:http:/ ...

  2. 《Cracking the Coding Interview》——第1章:数组和字符串——题目8

    2014-03-18 02:12 题目:判断一个字符串是否由另一个字符串循环移位而成. 解法:首先长度必须相等.然后将第一个串连拼两次,判断第二个串是否在这个连接串中. 代码: // 1.8 Assu ...

  3. C/C++学习笔记--指针(Pointer)

    定义指针 一般类型: type_name  *  var_name; 例如: int _var = 1555; int * _var_addr=&_var; 一般类型数组类:type_name ...

  4. Python网络编程(子进程的创建与处理、简单群聊工具)

    前言: 昨天我们已经了解了多进程的原理以及它的实际使用 Unix/Linux操作系统提供了一个fork()系统调用,它非常特殊.普通的函数调用,调用一次,返回一次, 但是fork()调用一次,返回两次 ...

  5. 易语言.开源(vip视频播放器源码)

    下载链接:https://pan.baidu.com/s/1ta1Ig3LOiOka-kr5xB18kw

  6. Scrapy 学习笔记(一)数据提取

    Scrapy 中常用的数据提取方式有三种:Css 选择器.XPath.正则表达式. Css 选择器 Web 中的 Css 选择器,本来是用于实现在特定 DOM 元素上应用花括号内的样式这样一个功能的. ...

  7. HDU 3577 Fast Arrangement ( 线段树 成段更新 区间最值 区间最大覆盖次数 )

    线段树成段更新+区间最值. 注意某人的乘车区间是[a, b-1],因为他在b站就下车了. #include <cstdio> #include <cstring> #inclu ...

  8. CocoaPods 安装与使用

    1.如果之前已经安装过的 gem list --local | grep cocoapods 会看到如下输出: cocoapods (1.1.1)cocoapods-deintegrate (1.0. ...

  9. SQL Server 重新编译存储过程的方式有三种

    SQL Server 中,强制重新编译存储过程的方式有三种: sp_recompile 系统存储过程强制在下次执行存储过程时对其重新编译.具体方法是:从过程缓存中删除现有计划,强制在下次运行该过程时创 ...

  10. Android初学者必知会的编程规范

    在安卓学习中,我们首先需要掌握的就是Android编程的一些规范,只有掌握了这些规范,后面的深入学习才能开展.今天小编在一个Android培训网站上搜罗了一些,Android初学者不得不知的开发规范, ...