此题就是在01背包问题的基础上求所能获得的第K大的价值。

详细做法是加一维去推当前背包容量第0到K个价值,而这些价值则是由dp[j-w[ i ] ][0到k]和dp[ j ][0到k]得到的,事实上就是2个数组合并之后排序,可是实际做法最好不要怎么做。由于你不知道总共同拥有多少种。而我们最多仅仅须要前K个大的即可了(由于可能2个数组加起来的组合数达不到K个),假设所有加起来数组开多大不清楚,所以能够选用归并排序中把左右2个有序数组合并成一个有序数组的方法来做。就是用2个变量去标记2个有序数组的头。然后比較。选了这个就这个变量加加,唯一不同的是不能有反复的,那么能够用一个非常巧妙的办法,就是在循环结束前推断要加进去的数是否跟前一个一样,假设不一样才加加。

AC代码:

#include<cstdio>
#include<ctype.h>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<ctime>
using namespace std;
#define push_back pb
int w[105],vol[105],vis[1005];
int dp[1005][35];
int main()
{
// freopen("input.txt","r",stdin);
// freopen("o1.txt","w",stdout); int i,j,k,t,n,v,K;
scanf("%d",&t);
while(t--)
{
memset(dp,0,sizeof(dp));
scanf("%d%d%d",&n,&v,&K);
for(i = 0; i < n; i++) scanf("%d",&w[i]);
for(i = 0; i < n; i++)
scanf("%d",&vol[i]);
for(i = 0; i <= v; i++) vis[i] = 1;
int temp[40];
for(i = 0; i < n; i++)
{
for(j = v; j >= vol[i]; j--)
{
memset(temp,0,sizeof(temp));
int a = 1,b = 1;
k = 1;
while((a<=vis[j-vol[i]] || b<=vis[j]) && k <= K)
{
if((dp[j-vol[i]][a]+w[i] > dp[j][b] && a <= vis[j-vol[i]]) || b > vis[j])
{
temp[k] = dp[j-vol[i]][a]+w[i];
a++;
}
else
{
temp[k] = dp[j][b];
b++;
}
if(temp[k] != temp[k-1]) k++;
}
vis[j] = k;
for(k = 1; k <= vis[j]; k++) dp[j][k] = temp[k];
}
}
printf("%d\n",dp[v][K]);
}
return 0;
}

HDU 2639 Bone Collector II(01背包变型)的更多相关文章

  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 (01背包,第k解)

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

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

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

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

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

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

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

  6. hdu 2639 Bone Collector II(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

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

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

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

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

随机推荐

  1. B/S系统间跨域单点登录设计思路

    基于B/S系统间单点登录 此处说的单点登录的概念,即不同系统公用一个登录界面.一处系统通过登录验证,在接入的各系统均为登录状态.一般有两种情景: 1)  一级域名相同 例如:tieba.baidu.c ...

  2. RoadTrip 学习笔记

    #RoadTrip 学习笔记 本篇是在Cmd Markdown中写完粘贴来的. RoadTrip介绍 RoadTrip 项目地址:https://github.com/romainguy/road-t ...

  3. [转] 与调试器共舞 - LLDB 的华尔兹

    你是否曾经苦恼于理解你的代码,而去尝试打印一个变量的值? NSLog(@"%@", whatIsInsideThisThing); 或者跳过一个函数调用来简化程序的行为? NSNu ...

  4. 4位bcd数转换为2进制数

    DATA   SEGMENTBUF    DW  1234HBUF1   DW  ?    ;2进制数放到buf1内存单元DATA   ENDSCODE   SEGMENTASSUME CS:CODE ...

  5. 【USACO 2.2.4】派对灯

    [描述] 在IOI98的节日宴会上,我们有N(10<=N<=100)盏彩色灯,他们分别从1到N被标上号码. 这些灯都连接到四个按钮: 按钮1:当按下此按钮,将改变所有的灯:本来亮着的灯就熄 ...

  6. 激活office 2013

    1.下载office 2013激活工具:microsoft toolkit 2.解压文件,运行Microsoft Toolkit.exe,选择office,即箭头标识处

  7. oracle常用SQL总结

    这里我们介绍的是 40+ 个非常有用的 Oracle 查询语句,主要涵盖了日期操作,获取服务器信息,获取执行状态,计算数据库大小等等方面的查询.这些是所有 Oracle 开发者都必备的技能,所以快快收 ...

  8. HTML5拖放

    HTML5拖放 <!doctype html> <html> <head> <meta charset="UTF-8"> <t ...

  9. 柔性数组-读《深度探索C++对象模型》有感 (转载)

    最近在看<深度探索C++对象模型>,对于Struct的用法中,发现有一些地方值得我们借鉴的地方,特此和大家分享一下,此间内容包含了网上搜集的一些资料,同时感谢提供这些信息的作者. 原文如下 ...

  10. 大数据学习之测试hdfs和mapreduce(二)

    上篇已经搭建好环境,本篇主要测试hadoop中的hdfs和mapreduce功能. 首先填坑:启动环境时发现DataNode启动不了.查看日志 从日志中可以看出,原因是因为datanode的clust ...