题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=2639

Bone Collector II

Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5817    Accepted Submission(s): 3067

Problem Description
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 231).
 
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
 
Author
teddy
 分析:
做的第一个背包求k大值问题。。。。
参考了大佬的博客好久:
这个是HUDU2602的变形题,HDU2602题参考我的这篇博客:
原来我们要求的是最大值,现在我们要求的是第K大值
 
参加资料:
实际上,一个正确的状态转移方程的求解过程遍历了所有可用的策略,也就覆盖了问题的所有方案。只不过由于是求最优解,所以其 它在任何一个策略上达不到最优的方案都被忽略了。如果把每个状态表示成一个大小为K的数组,并在这个数组中有序的保存该状态可取到的前K个最优值。那么, 对于任两个状态的max运算等价于两个由大到小的有序队列的合并。另外还要注意题目对于“第K优解”的定义,将策略不同但权值相同的两个方案是看作同一个解还是不同的解。如果是前者,则维护有序队列时要保证队列里的数没有重复的。
 
int dp[max_v][35];//dp[j][k] 代表背包容量为j时 第k大值
 
我的理解:
普通的01背包问题求解的时候其实遍历了所有可用的策略,但是不是最优的方案就忽略了,没有记录下来,比如max/min,只取了最大或者最小值,现在我们需要用到所有的策略,那么我们就用两个数组将原来忽略的值记录下来,将两个数组合并起来(降序,注意去重),然后将合并的数组存到dp[j][x] x属于从1到k
注意点:
1.合并数组要去重,因为策略不同但是权值相同的方案是看成同一个解的
去重和排序不能采用set,不然超时。。。
 
具体参考代码:
#include<bits/stdc++.h>
using namespace std;
#define max_v 10005
int v[max_v],w[max_v];
int dp[max_v][];//dp[j][k] 代表背包容量为j时 第k大值
int a[max_v],b[max_v];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,c,m;
scanf("%d %d %d",&n,&c,&m);
for(int i=;i<=n;i++)
{
scanf("%d",&v[i]);
}
for(int i=;i<=n;i++)
{
scanf("%d",&w[i]);
}
memset(dp,,sizeof(dp));
for(int i=;i<=n;i++)
{
for(int j=c;j>=w[i];j--)
{
int k;
// set <int,greater<int> > s;
for(k=;k<=m;k++ )
{
// a[k]=dp[j-w[i]][k]+v[i];
// b[k]=dp[j][k];
b[k]=dp[j-w[i]][k]+v[i];
a[k]=dp[j][k];
//s.insert(b[k]);
//s.insert(a[k]);
}
/* set<int,greater<int> >::iterator it;
int z=1;
for(it=s.begin();it!=s.end();it++)
{
dp[j][z++]=*it;
}
//使用set集合会超时 偷懒是不可能的了
*/ int x,y,z;
x=y=z=;
a[k]=b[k]=-;
while(z<=m&&(x<=m||y<=m))
{
if(a[x]>b[y])
{
dp[j][z]=a[x++];
}else
{
dp[j][z]=b[y++];
}
if(dp[j][z]!=dp[j][z-])
{
z++;
}
}
}
}
printf("%d\n",dp[c][m]);
}
return ;
}

HDU 2639(01背包求第K大值)的更多相关文章

  1. HDU 2639 01背包求第k大

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

  2. HDU 2639(01背包第K大)

    http://acm.hdu.edu.cn/showproblem.php?pid=2639 http://blog.csdn.net/lulipeng_cpp/article/details/758 ...

  3. Bone Collector II---hdu2639(01背包求第k优解)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2639求01背包的第k大解.合并两个有序序列 选取物品i,或不选.最终的结果,是我们能在O(1)的时间内 ...

  4. 关于01背包求第k优解

    引用:http://szy961124.blog.163.com/blog/static/132346674201092775320970/ 求次优解.第K优解 对于求次优解.第K优解类的问题,如果相 ...

  5. HDU 2639 01背包(分解)

    http://acm.hdu.edu.cn/showproblem.php?pid=2639 01背包第k优解,把每次的max分步列出来即可 #include<stdio.h> #incl ...

  6. POJ2985 The k-th Largest Group[树状数组求第k大值+并查集||treap+并查集]

    The k-th Largest Group Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 8807   Accepted ...

  7. 动态求区间K大值(权值线段树)

    我们知道我们可以通过主席树来维护静态区间第K大值.我们又知道主席树满足可加性,所以我们可以用树状数组来维护主席树,树状数组的每一个节点都可以开一颗主席树,然后一起做. 我们注意到树状数组的每一棵树都和 ...

  8. Bone Collector II HDU - 2639 01背包第k最大值

    题意: 01背包,找出第k最优解 题解: 对于01背包最优解我们肯定都很熟悉 第k最优解的话也就是在dp方程上加一个维度来存它的第k最优解(dp[i][j]代表,体积为i能获得的第j最大价值) 对于每 ...

  9. HDU 1171 Big Event in HDU【01背包/求两堆数分别求和以后的差最小】

    Big Event in HDU Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) T ...

随机推荐

  1. BZOJ3524: [Poi2014]Couriers(主席树)

    题意 题目链接 Sol 严格众数只会出现一次,那么建出主席树,维护子树siz,直接在树上二分即可 #include<bits/stdc++.h> #define LL long long ...

  2. marquee 滚动到文字上时停止滚动,自定义停止方法

    我要实现的效果如下图:当鼠标移到续费提醒文字上时,文字滚动停止,并出现后面的关闭按钮:当鼠标移出文字时,文字继续滚动,后面的关闭按钮不显示. 在网上查到的marquee停止滚动的的代码是这样的: &l ...

  3. CentOS 6.x 安装vnc

    https://www.cnblogs.com/pipci/p/7833581.html   1.安装vnc server [root@pxe ~]# yum install tigervnc-ser ...

  4. ArcEngine9.3迁移至ArcObject10.1

    以前写的程序,现在看起来真是相当的青涩,当时写的东西是显得多么地无知啊,很多应该写成一个类,有些需要优化,需要多线程,代码需要加密--总一种想修改的冲动.但这也需要时间和精力.下面准备将原来的程序进行 ...

  5. python学习笔记之——文件I/O

    1.print打印到屏幕 print "打印到屏幕" 2.读取读取键盘输入 (1)raw_input函数 raw_input([prompt]) 函数从标准输入读取一个行,并返回一 ...

  6. Python 利用Python编写简单网络爬虫实例3

    利用Python编写简单网络爬虫实例3 by:授客 QQ:1033553122 实验环境 python版本:3.3.5(2.7下报错 实验目的 获取目标网站“http://bbs.51testing. ...

  7. oracle 删除表的几种方法及回收站

    1.删除表结构和表数据 drop table 表名 [purge]  purge表示不放入回收站 2.删除表数据 delete from 表名 [where ...] 特点:高水位线不降:记录日志,速 ...

  8. ubuntu下配置JDK7环境变量

    ubuntu下JDK配置本质上和win是一样的: 1.去官网下载JDK7,找jdk-7u21-linux-i586.tar.gz并下载:http://www.oracle.com/technetwor ...

  9. Vue2学习笔记:数据交互vue-resource

    基本语法 必须引入一个库:vue-resource github地址 // 基于全局Vue对象使用http Vue.http.get('/someUrl', [options]).then(succe ...

  10. C语言占位符

    占位符就是先占住一个固定的位置,等着你再往里面添加内容的符号,广泛用于计算机中各类文档的编辑. 格式占位符(%)是在C/C++语言中格式输入函数,如 scanf.printf 等函数中使用.其意义就是 ...