HDU 2639 Bone Collector II [01 Backpack] + [Kth Best Decision]

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

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325086816&siteId=291194637