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[] sure) {
        int t;
        Scanner sc = new Scanner(System.in);
        t = sc.nextInt();
        while (t-- > 0) {
            int n, v, k;
            n = sc.nextInt();
            v = sc.nextInt();
            k = sc.nextInt();
            int[] val = new int[n + 1];
            int[] vol = new int[n + 1];
            int[][] dp = new int[v + 2][k + 2];
            int[] tp_a = new int[k + 2];
            int[] tp_b = new int[k + 2];

            for (int i = 0; i < n; i++) {
                val[i] = sc.nextInt();
            }
            for (int i = 0; i < n; i++) {
                vol[i] = sc.nextInt();
            }
            for (int i = 0; i < n; i++) {
                for (int j = v; j >= vol[i]; j--) {
                    for (int m = 1; m <= k; m++) {
                        tp_a[m] = dp[j][m];
                        tp_b[m] = dp[j - vol[i]][m] + val[i];
                    }
                    int tmp = 1, a = 1, b = 1;
                    tp_a[k+1] = tp_b[k+1] = -1;
                    //循环,依次将前K优的存到dp数组
                    while (tmp <= k && (a <= k || b <= k)) {
                        if (tp_a[a] > tp_b[b]) {
                            dp[j][tmp] = tp_a[a];
                            a++;
                        } else {
                            dp[j][tmp] = tp_b[b];
                            b++;
                        }
                        if (dp[j][tmp] != dp[j][tmp - 1])
                            tmp++;
                    }
                }
            }
            System.out.println(dp[v][k]);
        }
    }
}
时间: 2024-08-08 14:54:19

01背包之求第K优解——Bone Collector II的相关文章

hdu2639(背包求第k优解)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2639 题意:给出一行价值,一行体积,让你在v体积的范围内找出第k大的值 分析:dp[i][j][k]表示前i个物品容积为j时的第k优解.那么对于每种状态dp[i][j]都需要维护好前k优解. 每次根据前k优解进行每种取或不取第i件物品,用数组a记录取第i件物品,数组b记录不取,这样 数组a,b了所有能组成j的x种解,最后在x里取前k优解记录下来就好.剩下的肯定不是前k优解了... #include

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

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

【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

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

[HDOJ2639]Bone Collector II(第k优01背包)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2639 题意:求01背包的第k优解 dp(i, j)表示容量为j时的i优解 对于第二维的操作和01背包几乎一样,只是我们只需要关注每一次取的前k大个即可. 1 #include <algorithm> 2 #include <iostream> 3 #include <iomanip> 4 #include <cstring> 5 #include <cli

背包的第k优解[动态规划]

From easthong ☆背包的第k优解                 描述 Description     DD 和好朋友们要去爬山啦!他们一共有 K 个人,每个人都会背一个包.这些包的容量是相同的,都是 V.可以装进背包里的一共有 N 种物品,每种物品都有给定的体积和价值. 在 DD 看来,合理的背包安排方案是这样的: 1. 每个人背包里装的物品的总体积恰等于包的容量.  2. 每个包里的每种物品最多只有一件,但两个不同的包中可以存在相同的物品.  3. 任意两个人,他们包里的物品清单

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

DP2_第K优解

转载:http://m.blog.csdn.net/blog/a511310132/13465985 对于求次优解.第K优解类的问题,如果相应的最优解问题能写出状态转移方程.用动态规划解决,那么求次优解往往可以相同的复杂度解决,第K优解则比求最优解的复杂度上多一个系数K.其基本思想是将每个状态都表示成有序队列,将状态转移方程中的max/min转化成有序队列的合并.这里仍然以01背包为例讲解一下.首先看01背包求最优解的状态转移方程:f[i][v]=max{f[i-1][v],f[i-1][v-c