题目大意

一个人收藏骨头,有 n 个骨头,每个骨头有体积和价值,问能够装在容量为 V 的背包中,能获得的第 k 大(去重后)价值是多少。

样例

样例输入 1

5 10 2
1 2 3 4 5
5 4 3 2 1

样例输出 1

12

样例输入 2

5 10 12
1 2 3 4 5
5 4 3 2 1

样例输出 2

2

分析

  • 跑暴力显然不优秀,每种物品可选可不选,最多 \(2^n\) 种不同的方案,也就对应这么多价值,显然如果都存下再排序输出结果,简单了事,但是显然时间和空间都承受不住。
  • 当然在跑背包的时候,我们每次的决策都是在前面的基础上求得当前阶段每个状态的最优解。如果单纯的想最后把数组中所有的值都拿来排序,也不可行。整个转移过程并不能保证比最优解小一点的就是次大值。
  • 我们可以针对每个容量 j,同时维护 k 个值,来保存放到容量 j 的时候前 k 大价值。在此基础上我们再考虑针对第 i 件物品的转移:
    • 定义 \(f[i][j][k]\) 表示前 i 件物品放到容量为 j 背包中,获得的第 k 大价值,由于第 i 捡物品状态转移的时候只跟前 i-1 的状态有关,因此还可以简化成二维,即 \(f[j][k]\)。
    • 放与不放第 i 件物品的最大值从何而来?很显然,就是普通的转移方程的两个值取较大者:\(max\{f[j][1], f[j-vi][1]+wi\}\),即放与不放分别有一个最大值,从二者当中选取一个作为最大。
    • 继续考虑第二大的候选值有哪些?
      1. 有可能该物品性价比极其低,那显然不选它可能是最好的,这样有可能最大值和次大值都为不放该物品对应的值;
      2. 有可能该物品的性价比超高,那显然选择它可能是最好的,这样有可能最大值和次大值都为放下该物品对应的值;
      3. 因此次大值的候选值会有 4 个:\(f[j][1], f[j][2], f[j-vi][1]+wi, f[j-vi][2]+wi\);
      4. 以此类推,针对每个容量,都会有 2k 个候选值。如果 \(f[j]\) 和 \(f[j-vi]\) 都存在 k 个不同值,那么 当前的 \(f[j]\) 肯定能够从中得到 k 个不同的值。
    • 另外一个问题就是如何选取 k 个不同值:
      1. 可以 sort 一遍再去重,简单粗暴有效
      2. 节俭归并排序中的合并,因为 \(f[j][k]\) 和 \(f[j-vi][k]+wi\) 都分别是降序序列,因此搞两个数组,从中不断取数合并在一起就可以了,代码略长,但是效率高不少

代码(归并的方法)

// 归并排序法合并两部分,取前kth个数
void bag() {
for (int i = 1; i <= n; ++i) {
for (int j = vol; j >= cost[i]; --j) {
int a[K] = {}, b[K] = {};
for (int k = 1; k <= kth; ++k) {
a[k] = dp[j][k];
b[k] = dp[j-cost[i]][k]+val[i];
}
a[kth+1] = -1;
b[kth+1] = -1; // 合并
int k = 1, x = 1, y = 1;
while (k <= kth && (x <= kth || y <= kth)) {
dp[j][k] = a[x] > b[y] ? a[x++] : b[y++];
if (dp[j][k] != dp[j][k-1]) {
k++;
}
}
}
}
printf("%d\n", dp[vol][kth]);
}

HDU - 2639 Bone Collector II 题解的更多相关文章

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

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

  2. hdu 2639 Bone Collector II

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

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

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

  4. 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 ...

  5. 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 ...

  6. hdu 2639 Bone Collector II (01背包,求第k优解)

    这题和典型的01背包求最优解不同,是要求第k优解,所以,最直观的想法就是在01背包的基础上再增加一维表示第k大时的价值.具体思路见下面的参考链接,说的很详细 参考连接:http://laiba2004 ...

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

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

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

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

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

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

随机推荐

  1. 实战!我用 Wireshark 让你“看得见“ TCP

    每日一句英语学习,每天进步一点点: 前言 为了让大家更容易「看得见」 TCP,我搭建不少测试环境,并且数据包抓很多次,花费了不少时间,才抓到比较容易分析的数据包. 接下来丢包.乱序.超时重传.快速重传 ...

  2. 「雕爷学编程」Arduino动手做(13)——触摸开关模块

    37款传感器和模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的.鉴于本人手头积累了一些传感器与模块,依照实践出真知(动手试试)的理念,以学习和交流为目的,这里准备 ...

  3. Template模式C++实现

    #include <iostream> using namespace std; class AbstractClass { public: void TemplateMethod() { ...

  4. Spring Cloud Alibaba入门实战之nacos(一)

    Spring Cloud Alibaba入门实战之nacos(一) 前情介绍 ​ Spring Cloud Alibaba 是阿里巴巴提供的新一代的微服务解决方案,相信会有越来越多采用微服务架构的公司 ...

  5. HTML新特性--canvas绘图-文本

    一.html5新特性--canvas绘图-文本(重点) #常用方法与属性 -ctx.strokeText(str,x,y);   绘制描边文字(空心) str:绘制文本 x,y:字符串左上角位置(以文 ...

  6. ES6---面向对象上的简化

    一.ES6---面向对象上的简化 1.单个对象提供了2处简化: 1.1 如果对象的属性来自于对象外的变量,且变量名刚好和属性名相同.则不用写两遍相同的名字, 只要写一遍即可. 1.2 所有对象的方法, ...

  7. 模拟SWPU邮件登录页面

    模拟SWPU邮件登录页面设计流程 一.开发工具准备 本次开发该页面时使用的开发工具为vscode—— 在下载安装完成后,需要下载各类插件——如汉化.通过浏览器打开网页插件等. 二.开发过程 首先,打开 ...

  8. element-ui的el-table和el-form嵌套使用表单校验

    表格中嵌套使用表单验证 表格是el-table自动获取的后台数据,每行都有el-input的验证,这样一个rules的规则就不能匹配到每一行,所以要是用动态的prop和rules规则 需求如下,要对告 ...

  9. Spring Beans 自动装配 简介

    Beans 自动装配 Spring 容器可以在不使用<constructor-arg>和<property> 元素的情况下自动装配相互协作的 bean 之间的关系,这有助于减少 ...

  10. Java——关键字instanceof

    instanceof 判断一个对象是否为一个类的实例,是为true ,否为false class Animal{} class Cat extends Animal{} /**instanceof 判 ...