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

Source

百万秦关终属楚

题意:

有n件物品,每件物品有价值和体积,有容量为m的背包,求能够得到的第k大的价值

代码:

//以前的dp[V]数组再加一维dp[V]K]表示V状态时第k大的值,当枚举到第i个物品时
//dp[i][V]=max(dp[i-1][V],dp[i-1][V-v]),当前状态由两个状态转移来的所以前k大的值
//也是由两个状态的前k大的值转移来的。注意本体价值重复的算一个。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN=109;
const int MAXV=1009;
const int MAXK=39;
int dp[MAXV][MAXK];
int val[MAXN],vol[MAXN];
int N,V,K;
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",&val[i]);
        for(int i=1;i<=N;i++)
            scanf("%d",&vol[i]);
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=N;i++){
            for(int j=V;j>=vol[i];j--){
                int a1=1,a2=1,p1[39],p2[39];
                for(int c=1;c<=K;c++){
                    p1[c]=dp[j][c];
                    p2[c]=dp[j-vol[i]][c]+val[i];
                }
                p1[K+1]=p2[K+1]=-1;
                int c=0;
                while(c!=K){
                    int tmp=max(p1[a1],p2[a2]);
                    if(tmp==p1[a1]){
                        a1++;
                        if(tmp!=dp[j][c]) dp[j][++c]=tmp;
                        else if(tmp==0) dp[j][++c]=0;
                    }
                    else if(tmp==p2[a2]){
                        a2++;
                        if(tmp!=dp[j][c]) dp[j][++c]=tmp;
                        else if(tmp==0) dp[j][++c]=0;
                    }
                }
                //cout<<i<<" "<<j<<endl;
                //for(int k=1;k<=K;k++) cout<<dp[j][k]<<" ";
                //cout<<endl;
            }
        }
        printf("%d\n",dp[V][K]);
    }
    return 0;
}
时间: 2024-10-13 11:53:54

HDU 2639 背包第k优解的相关文章

01背包 HDU 2639,第K优解

只要每次都保存前k优解就可以了 注意当价值一样时,只算一种,所以要进行去重复 的操作 用到了unique, 1 2 2 4 0 0 unique之后1 2 4 0 0 2 Bone Collector II Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2433    Accepted Submission(s): 1277 Prob

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

杭电 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】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 pa

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

2639-Bone Collector II (01背包之第k优解)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2639 求第k优解的关键代码: 用两个数组记录两种状态(选择或不选择),并且只要记录前k次.在这两个数组中都是前k次可能的最优解.所以我们只要把这两个数组做比较,一直排到k就行了 题目代码: 1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 int dp

第k优解 hdu 2639

#include<iostream> #include<cstdio> #include<cstring> #define maxn 110 using namespace std; int w[110],v[110],f[1010][110],a[110],b[110]; //f[j][k]表示重量为j时的第k优解 int main() { int t; scanf("%d",&t); while(t--) { int n,m,i,j,k,

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

01背包之求第K优解——Bone Collector II

http://acm.hdu.edu.cn/showproblem.php?pid=2639 题目大意是,往背包里赛骨头,求第K优解,在普通01背包的基础上,增加一维空间,那么F[i,v,k]可以理解为前i个物品,放入容量v的背包时,第K优解的值.时间复杂度为O(NVK). Talk is cheap. 看代码吧. import java.util.Scanner; public class BoneCollector { public static void main(String[] sur