[HDU 2639]Bone Collector II

Description

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$大背包。

我们容易想到为背包数组再开一维$k$,

由于序列单调,每次转移的时候归并排序就好。

 1 //It is made by Awson on 2017.9.25
 2 #include <set>
 3 #include <map>
 4 #include <ctime>
 5 #include <cmath>
 6 #include <queue>
 7 #include <stack>
 8 #include <vector>
 9 #include <cstdio>
10 #include <string>
11 #include <cstring>
12 #include <cstdlib>
13 #include <iostream>
14 #include <algorithm>
15 #define LL long long
16 #define Max(a, b) ((a) > (b) ? (a) : (b))
17 #define Min(a, b) ((a) < (b) ? (a) : (b))
18 #define sqr(x) ((x)*(x))
19 using namespace std;
20 const int N = 100;
21 const int V = 1000;
22 const int K = 30;
23 
24 int n, m, k;
25 int w[N+5], v[N+5];
26 int f[V+5][K+5];
27 
28 void work() {
29     scanf("%d%d%d", &n , &m, &k);
30     for (int i = 1; i <= n; i++) scanf("%d", &w[i]);
31     for (int i = 1; i <= n; i++) scanf("%d", &v[i]);
32     memset(f, 0, sizeof(f));
33     for (int i = 1; i <= n; i++)
34     for (int j = m; j >= v[i]; j--) {
35         int a[V+5], b[V+5];
36         for (int p = 1; p <= k; p++)
37         a[p] = f[j][p];
38         for (int p = 1; p <= k; p++)
39         b[p] = f[j-v[i]][p]+w[i];
40         a[k+1] = b[k+1] = -1;
41         int la = 1, lb = 1, l = 1;
42         while (l<=k && (la <= k || lb <= k)) {
43         if (a[la] >= b[lb]) f[j][l] = a[la++];
44         else f[j][l] = b[lb++];
45         if (f[j][l] != f[j][l-1]) l++;
46         }
47     }
48     printf("%d
", f[m][k]);
49 }
50 int main() {
51     int t;
52     scanf("%d", &t);
53     while (t--)
54     work();
55     return 0;
56 }
原文地址:https://www.cnblogs.com/NaVi-Awson/p/7592391.html