题目链接:

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大值问题。。。。
参考了大佬的博客好久:
大佬博客题解:https://blog.csdn.net/lulipeng_cpp/article/details/7584981
这个是HUDU2602的变形题,HDU2602题参考我的这篇博客:
https://www.cnblogs.com/yinbiao/p/9016365.html
原来我们要求的是最大值,现在我们要求的是第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][35];//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=1;i<=n;i++){scanf("%d",&v[i]);}for(int i=1;i<=n;i++){scanf("%d",&w[i]);}memset(dp,0,sizeof(dp));for(int i=1;i<=n;i++){for(int j=c;j>=w[i];j--){int k;// set <int,greater<int> > s;for(k=1;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=1;a[k]=b[k]=-1;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-1]){z++;}}}}printf("%d\n",dp[c][m]);}return 0;
}

转载于:https://www.cnblogs.com/yinbiao/p/9099194.html

HDU 2639(01背包求第K大值)相关推荐

  1. hdu 3732(01背包转多重背包)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3732 思路:这么大的数据,用01背包肯定会TLE的,01背包转多重背包..最多也就11*11=121件 ...

  2. [01背包] 背包问题求具体方案(01背包+求方案数+思维)

    文章目录 0. 前言 1. 01背包+求方案数+思维 0. 前言 相关: [背包] 背包问题算法模板(模板) 1. 01背包+求方案数+思维 12. 背包问题求具体方案 求方案数也是背包问题.dp 的 ...

  3. 堆实战(动态数据流求top k大元素,动态数据流求中位数)

    动态数据集合中求top k大元素 第1大,第2大 ...第k大 k是这群体里最小的所以要建立个小顶堆 只需要维护一个大小为k的小顶堆 即可当来的元素(newCome)> 堆顶元素(smallTo ...

  4. 树状数组与离散化与求第K大模板

    树状数组模板: //Cnt为数组的界 //cnt[i]为编号或者数值上小于id的数量 void Update(LL Id) {while(Id<=Cnt){cnt[Id]++;Id+=lowbi ...

  5. 无序数组求第k大的数 python_整数无序数组求第K大数

    import java.util.Scanner; /** * 类似与求第k小的问题 * 求第k大相当于求第n-k+1小,n为数组长度 * * 著名的BFPRT算法可保证在线性时间内得到结果. * h ...

  6. 两个排序数组中求第k大的sum(a+b)

    两个数组A,B. 是排好序的,a是A中的元素,b是B中的元素,求第k大的sum(a+b) 先把a[1]+b[1]放入堆中, 每次从堆中取得最小值,设a[i]+b[j],并扩展a[i+1]+b[j] , ...

  7. 单峰数组求第k大算法

    单峰数组实际上可以看成两个有序的数组,这个问题就转变成了两个有序数组求第k大. 容易想到的算法是对这两个数组进行归并,生成一个新的有序数组,求出第k大之后就可以立刻停止,复杂度是O(k)的. 但是还有 ...

  8. [01背包] 数字组合(01背包+求方案数)

    文章目录 0. 前言 1. 01背包求方案数 0. 前言 相关: [背包] 背包问题算法模板(模板) 1. 01背包求方案数 278. 数字组合 将 M 看作背包容量,每个数看成一个物品,Ai 看成是 ...

  9. 算法题 求第K大的数

    题目描述:在乱序数组中求第K大的数 思路:立刻想到的是当然先排序然后取数.但是提问者明显不是想这么解.上网查了下原来是快排思路. 利用快排的思想,从数组arr中随机找出一个元素X,把数组分成两部分ar ...

最新文章

  1. Python核心编程笔记---- print
  2. python正则表达式,看完这篇文章就够了...
  3. Linux 之三 静态库及动态库的编写和使用
  4. Duplicate Elimination in Scrapy(转)
  5. 使用Java Spring消费MySQL中的数据库存储过程
  6. appengine_Google Appengine登台服务器操作方法
  7. 做虚拟化服务器的配资一致嘛,服务器虚拟化技术在校园网管理中的应用探讨.pdf...
  8. penpyxl basic function demo code
  9. 绘制函数z = x2 + y2所表示的三维网格图
  10. 参数化曲线-微分几何
  11. OutMan——C语言中字符串处理函数、内存管理和内存分区
  12. 汇编语言--微机CPU的指令系统(五)(循环指令)
  13. throw 关键字,throw 必须写在方法体中,并且 throw new xxxException的话,如果是运行时的异常可以不用管,如果是编译的异常需要进行处理
  14. H5--drag拖拽事件
  15. openlayers中绘制态势箭头、进击箭头、钳击箭头等
  16. 西瓜书第四章习题及答案
  17. 如何使用cpolar穿透内网访问监控摄像头
  18. 共享充电宝广告机功能与特点
  19. ESP32+DHT11+Arduino连接phpstudy的本地数据库
  20. 如何生成二维码?生成二维码其实很简单

热门文章

  1. 提交信息html模板,提交留言HTML模板代码
  2. 结构方程模型-调节(干扰)效应检验(一)
  3. 10个每个开发人员都喜欢的JavaScript模式
  4. socket连接时间太长受什么原因影响?_光纤收发器的六个指示灯都代表什么?
  5. matlab图像处理 推荐,Matlab计算机视觉、图像处理工具箱推荐
  6. Linux编辑firmware的文件,Linux中request_firmware 的用法
  7. 视频列表页html,视频列表.html
  8. qzone.class.php,[宜配屋]听图阁
  9. Java面试题:List一边遍历,一边删除
  10. C++ 实现把非静态成员函数作为回调函数(非static)