【HDU2639】Bone Collector II(01背包第k优解)

Bone Collector II

Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 2948    Accepted Submission(s): 1526

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

大概就是求能装下的第k多的价值

dp数组增加一维 作为第l多的价值

dp[j][l]   dp[j-vo[i]][l] + va[i] 用数组a和b分别存下 之后放在一起判断大小排序 其他同01背包

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

const int maxn = 1011;
int va[maxn], vo[maxn];
int n, v, k;
int dp[maxn][55];
int a[55], b[55];

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", &va[i]);
        }
        for(int i = 1; i <= n; ++i){
            scanf("%d", &vo[i]);
        }
        memset(dp, 0, sizeof(dp));

        for(int i = 1; i <= n; ++i){
            for(int j = v; j >= vo[i]; --j){
                for(int l = 1; l <= k; ++l){
                    a[l] = dp[j][l];
                    b[l] = dp[j-vo[i]][l] + va[i];
                }

                a[k+1] = b[k+1] = -1;
                int x = 1, y = 1, w = 1;
                while(w <= k && (x <= k || y <= k)){
                    if(a[x] > b[y]){
                        dp[j][w] = a[x++];
                    }
                    else{
                        dp[j][w] = b[y++];
                    }

                    if(w == 1 || dp[j][w] != dp[j][w-1]){
                        ++w;
                    }
                }
            }
        }

        printf("%d\n", dp[v][k]);
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-10 07:20:52

【HDU2639】Bone Collector II(01背包第k优解)的相关文章

HDU2639Bone Collector II[01背包第k优值]

Bone Collector II Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4229    Accepted Submission(s): 2205 Problem Description The title of this problem is familiar,isn't it?yeah,if you had took par

HDU 2639 Bone Collector II (DP 第k优解)

题意:输入t,t组测试样例,每组样例输入 n, v, k. 接着输入n个物品的价值,再输入n个物品的体积.求k优解. 分析:dp[n][v][k]表示n个物品,在体积不超过v的情况,第k大的值是多少.dp[i][v][k]与dp[i-1][v][k]与dp[i-1][v-volume[i]]+value[i]有关. #include <iostream> #include <cstdio> #include <cstring> #include <algorith

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

此题就是在01背包问题的基础上求所能获得的第K大的价值. 具体做法是加一维去推当前背包容量第0到K个价值,而这些价值则是由dp[j-w[ i ] ][0到k]和dp[ j ][0到k]得到的,其实就是2个数组合并之后排序,但是实际做法最好不要怎么做,因为你不知道总共有多少种,而我们最多只需要前K个大的就行了(因为可能2个数组加起来的组合数达不到K个),如果全部加起来数组开多大不清楚,所以可以选用归并排序中把左右2个有序数组合并成一个有序数组的方法来做,就是用2个变量去标记2个有序数组的头,然后比

HDU 2639 (01背包第k优解)

/* 01背包第k优解问题 f[i][j][k] 前i个物品体积为j的第k优解 对于每次的ij状态 记下之前的两种状态 i-1 j-w[i] (选i) i-1 j (不选i) 分别k个 然后归并排序并且去重生成ij状态的前k优解 */ #include<iostream> #include<cstdio> #include<cstring> #define maxn 1010 using namespace std; int T,n,m,k,c[maxn],v[maxn

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

Bone Collector II Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4739    Accepted Submission(s): 2470 Problem Description The title of this problem is familiar,isn't it?yeah,if you had took pa

杭电 2639 Bone Collector II【01背包第k优解】

解题思路:对于01背包的状态转移方程式f[v]=max(f[v],f[v-c[i]+w[i]]);其实01背包记录了每一个装法的背包值,但是在01背包中我们通常求的是最优解, 即为取的是f[v],f[v-c[i]]+w[i]中的最大值,但是现在要求第k大的值,我们就分别用两个数组保留f[v]的前k个值,f[v-c[i]]+w[i]的前k个值,再将这两个数组合并,取第k名. 即f的数组会增加一维. http://blog.csdn.net/lulipeng_cpp/article/details/

hdu2639 01背包第K优解

#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> using namespace std; int dp[1005][35],val[1005],vol[1005], A[35],B[35]; int main() { int T,n,v,K,k; scanf("%d",&T); while

hdu 2639 Bone Collector II 01背包问题 求第K大最优值。。

Bone Collector II Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2665    Accepted Submission(s): 1392 Problem Description The title of this problem is familiar,isn't it?yeah,if you had took pa

HDU 2639 背包第k优解

Bone Collector II Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4824    Accepted Submission(s): 2514 Problem Description The title of this problem is familiar,isn't it?yeah,if you had took par