HDU2639Bone Collector II(01背包变形)
01背包,求第k大。
以前看k短路的时候看过代码以为懂了 = =结果还是跑去看了别人的代码才会。果然要自己写一遍才行啊 0.0难得1A。。
每次把可能的2k种求出来,求前k个。注意要不一样的k个数。。
/************************************************************** Problem : 2639 ( Bone Collector II ) Judge Status : Accepted RunId : 15212165 Language : G++ Author : G_lory Code Render Status : Rendered By HDOJ G++ Code Render Version 0.01 Beta ***************************************************************/ #include <iostream> #include <cstdio> #include <cstring> using namespace std; //N <= 100 , V <= 1000 , K <= 30 const int MAXN = 105; const int MAXV = 1005; const int MAXK = 35; int val[MAXN]; int vol[MAXN]; int dp[MAXV][MAXK]; int a[MAXK], b[MAXK]; int main() { int n, v, k; int t; cin >> t; while (t--) { memset(dp, 0, sizeof dp); cin >> n >> v >> k; for (int i = 0; i < n; ++i) cin >> val[i]; for (int i = 0; i < n; ++i) cin >> vol[i]; for (int i = 0; i < n; ++i) { for (int j = v; j >= vol[i]; --j) { for (int q = 0; q < k; ++q) { a[q] = dp[j][q]; b[q] = dp[j - vol[i]][q] + val[i]; } int ic = 0, jc = 0; int ck = 0; while (ic < k && jc < k && ck < k) { if (a[ic] < b[jc]) { if (ck == 0 || b[jc] < dp[j][ck - 1]) dp[j][ck++] = b[jc]; jc++; } else { if (ck == 0 || a[ic] < dp[j][ck - 1]) dp[j][ck++] = a[ic]; ic++; } } while (ic < k && ck < k) { if (ck == 0 || a[ic] < dp[j][ck - 1]) dp[j][ck++] = a[ic]; ic++; } while (jc < k && ck < k) { if (ck == 0 || b[jc] < dp[j][ck - 1]) dp[j][ck++] = b[jc]; jc++; } } } cout << dp[v][k - 1] << endl; } return 0; }