Question link: https://vjudge.net/contest/103424#problem/H
The main idea of the title:
It is similar to the 01 backpack template question, except that we ask for the Kth largest total value.
Problem solving analysis:
This question can be compared to, to calculate the top n of the entire grade, you can sort the top n of each class
The same is true for the k-th knapsack
Now one more dimension is added to the 01 knapsack, dp[v][k], which represents the kth largest value in the v space. . .
When updating, there are two arrays A and B. A records the selection of the i-th item in descending order, and B records the unselected order from large to small, and then merges AB, and selects the top k largest in AB. Merged into dp. . .
#include <iostream> #include <cstdio> using namespace std; #define max(a,b) ((a)>(b)?(a):(b)) const int maxn = 1005; int main() { int T; scanf("%d", &T); int dp[maxn][33], val[maxn], vol[maxn], A[33], B[33]; while (T--) { int n, v, k; scanf("%d %d %d", &n, &v, &k); int i, j, kk; for (i = 0; i<n; i++) scanf("%d", &val[i]); for (i = 0; i<n; i++) scanf("%d", &vol[i]); memset(dp, 0, sizeof(dp)); int a, b, c; for (i = 0; i<n; i++) for (j = v; j >= vol[i]; j--) { for (kk = 1; kk <= k; kk++) { A[kk] = dp[j - vol[i]][kk] + val[i]; B[kk] = dp[j][kk]; } A[kk] = -1, B[kk] = -1; //定义边界 a = b = c = 1; while (c <= k && (A[a] != -1 || B[b] != -1)) { if (A[a] > B[b]) // pick the larger of the two numbers dp[j][c] = A[a++ ]; else dp[j][c] = B[b++ ] ; if (dp[j][c] != dp[j][c - 1 ]) // Conversely, if dp[j][c]==dp[j][c-1], the value of c Do not increase, wait until the next number in the A or B array, overwrite dp[j][c], the effect is to remove the same situation c++ ; } } printf("%d\n", dp[v][k]); } return 0; }
2018-04-30