题目链接【http://acm.hdu.edu.cn/showproblem.php?pid=2639】
题意:求第k大背包。
题解:利用二路归并的思想,求解第K大的值。
#include<bits/stdc++.h> using namespace std; typedef long long LL; const int MAXN = 1050; int dp[MAXN][35], w[MAXN], v[MAXN]; int N, W, K; int A[35], B[35]; void super_kth() { for(int i = 1; i <= N; i++) { for(int j = W; j >= w[i]; j--) { for(int l = 1; l <= K; l++) { A[l] = dp[j - w[i]][l] + v[i]; //放i B[l] = dp[j][l];//不放i } int nu = 1, x = 1, y = 1; A[K + 1] = -1; B[K + 1] = -1; while(nu <= K && (A[x] != -1 || B[y] != -1)) { if(A[x] > B[y]) dp[j][nu] = A[x++]; else dp[j][nu] = B[y++]; if(dp[j][nu] != dp[j][nu - 1])//不相等的第k大背包 nu++; } } } printf("%d ", dp[W][K]); } int main () { int T; scanf("%d", &T); while(T--) { memset(dp, 0, sizeof(dp)); scanf("%d%d%d", &N, &W, &K); for(int i = 1; i <= N; i++) scanf("%d", &v[i]); for(int i = 1; i <= N; i++) scanf("%d", &w[i]); super_kth(); } return 0; }