HDU 2639 Bone Collector II (01背包第k优解 好题)

来源:互联网 发布:记住英国历史 知乎 编辑:程序博客网 时间:2024/06/06 05:30

Bone Collector II

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


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
35 10 21 2 3 4 55 4 3 2 15 10 121 2 3 4 55 4 3 2 15 10 161 2 3 4 55 4 3 2 1
 

Sample Output
1220
 

Author
teddy
 

Source
百万秦关终属楚
 

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2639

题目大意:求01背包的第k优解

题目分析:摘取自网上:对于求次优解、第K优解类的问题,如果相应的最优解问题能写出状态转移方程、用动态规划解决,那么求次优解往往可以相同的复杂度解决,第K优解则比求最优解的复杂度上多一个系数K。其基本思想是将每个状态都表示成有序队列,将状态转移方程中的max/min转化成有序队列的合并。这里仍然以01背包为例讲解一下。
首先看01背包求最优解的状态转移方程:f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}。如果要求第K优解,那么状态f[i][v]就应该是一个大小为K的数组f[i][v][1..K]。其中f[i][v][k]表示前i个物品、背包大小为v时,第k优解的值。“f[i][v]是一个大小为K的数组”这一句,熟悉C语言的同学可能比较好理解,或者也可以简单地理解为在原来的方程中加了一维。显然f[i][v][1..K]这K个数是由大到小排列的,所以我们把它认为是一个有序队列。然后原方程就可以解释为:f[i][v]这个有序队列是由f[i-1][v]和f[i-1][v-c[i]]+w[i]这两个有序队列合并得到的。有序队列f[i-1][v]即f[i-1][v][1..K],f[i-1][v-c[i]]+w[i]则理解为在f[i-1][v-c[i]][1..K]的每个数上加上w[i]后得到的有序队列。合并这两个有序队列并将结果(的前K项)储存到f[i][v][1..K]中的复杂度是O(K)。最后的答案是f[N][V][K]。总的复杂度是O(NVK)。为什么这个方法正确呢?实际上,一个正确的状态转移方程的求解过程遍历了所有可用的策略,也就覆盖了问题的所有方案。只不过由于是求最优解,所以其它在任何一个策略上达不到最优的方案都被忽略了。如果把每个状态表示成一个大小为K的数组,并在这个数组中有序的保存该状态可取到的前K个最优值。那么,对于任两个状态的max运算等价于两个由大到小的有序队列的合并。另外还要注意题目对于“第K优解”的定义,将策略不同但权值相同的两个方案是看作同一个解还是不同的解。如果是前者,则维护有序队列时要保证队列里的数没有重复的。
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;int const MAX = 105;int n, V, k;int v[MAX], w[MAX], a[MAX], b[MAX];int dp[1005][35];int main(){int T;scanf("%d", &T);while(T--){scanf("%d %d %d", &n, &V, &k);for(int i = 1; i <= n; i++)scanf("%d", &w[i]);for(int i = 1; i <= n; i++)scanf("%d", &v[i]);memset(dp, 0, sizeof(dp));for(int i = 1; i <= n; i++){for(int j = V; j >= v[i]; j--){for(int l = 1; l <= k; l++){a[l] = dp[j][l];b[l] = dp[j - v[i]][l] + w[i];}a[k + 1] = -1;b[k + 1] = -1;int x = 1, y = 1, z = 1;while(z <= k && (a[x] >= 0 || b[y] >= 0)){if(a[x] > b[y])dp[j][z] = a[x ++];elsedp[j][z] = b[y ++];if(dp[j][z] != dp[j][z - 1])z ++;}}}printf("%d\n", dp[V][k]);}}


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 动漫大嫂后篇 年轻的大嫂中国 韩国电影青春中国字幕 小弟睡大嫂的电视剧 强入朋友妻在线播放 中午阳台上退掉表嫂裙子 被老公在厨房要到腿软 后妈的味道中文字幕 妻子和她的学生中文字幕 朋友的妻子和母亲hd高清中文字幕 丈夫面前侵犯入侵在线看 兄弟侵犯大嫂5中文字幕在线 暴风雨夜与妻子朋友独处 年轻的女老板3中文字 兄弟侵犯大嫂中文字幕迅雷视频 大香煮蕉伊在线网视频推手 91青青城线在人线免费人人人 91青青城人线在人线 95青青成线人人 青青成线小说 青青成线人线免 第一成一肉区免 费91 欧洲第一肉场 欧洲第一成肉区免 费91ap 免费欧洲第一成肉区免 费91 欧洲第一成一肉区免 费9 欧洲第一成一肉区免 费91人雨马 欧洲笫一肉区l1041 久碰人人澡人人澡人人澡人人澡 看欧洲第一成肉区免 免费在 线人擦人人搞人视频人人人 人人差人人搞人视频 人人看人人揉人人捏动漫 超越人人夜人人看视频 人人玩人人弄人槽视频动漫 草人人拍人人躁 人人人人看人谢97 免费在 线人擦人人搞人视频动漫视频 人人看人人揉人人捏视频 青青成线人线免费公开 亚成区1216成线人