[HDOJ2639]Bone Collector II(第k优01背包)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2639

题意:求01背包的第k优解

dp(i, j)表示容量为j时的i优解

对于第二维的操作和01背包几乎一样,只是我们只需要关注每一次取的前k大个即可。

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <iomanip>
 4 #include <cstring>
 5 #include <climits>
 6 #include <complex>
 7 #include <fstream>
 8 #include <cassert>
 9 #include <cstdio>
10 #include <bitset>
11 #include <vector>
12 #include <deque>
13 #include <queue>
14 #include <stack>
15 #include <ctime>
16 #include <set>
17 #include <map>
18 #include <cmath>
19
20 using namespace std;
21
22 const int maxn = 1010;
23 int n, m, k;
24 int v[maxn], w[maxn];
25 int dp[maxn][maxn];
26 int d[maxn];
27
28 int main() {
29     freopen("in", "r", stdin);
30     int T;
31     scanf("%d", &T);
32     while(T--) {
33         scanf("%d%d%d", &n, &m, &k);
34         for(int i = 0; i < n; i++) {
35             scanf("%d", &v[i]);
36         }
37         for(int i = 0; i < n; i++) {
38             scanf("%d", &w[i]);
39         }
40         memset(dp, 0, sizeof(dp));
41         for(int i = 0; i < n; i++) {
42             for(int j = m; j >= w[i]; j--) {
43                 int cnt = 0;
44                 for(int p = 1; p <= k; p++) {
45                     d[cnt++] = dp[p][j];
46                     if(j - w[i] >= 0) {
47                         d[cnt++] = dp[p][j-w[i]] + v[i];
48                     }
49                 }
50                 sort(d, d+cnt, greater<int>());
51                 cnt = unique(d, d+cnt) - d;
52                 int q = 1;
53                 for(int p = 0; p < cnt; p++) {
54                     dp[q++][j] = d[p];
55                 }
56             }
57         }
58         printf("%d\n", dp[k][m]);
59     }
60     return 0;
61 }
时间: 2024-10-11 02:09:18

[HDOJ2639]Bone Collector II(第k优01背包)的相关文章

【HDU2639】Bone Collector II(01背包第k优解)

Bone Collector II Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2948    Accepted Submission(s): 1526 Problem Description The title of this problem is familiar,isn't it?yeah,if you had took pa

hdu 2639 Bone Collector II(01背包 第K大价值)

Bone Collector II Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3355    Accepted Submission(s): 1726 Problem Description The title of this problem is familiar,isn't it?yeah,if you had took par

HDU 2639 Bone Collector II(01背包变形【第K大最优解】)

Bone Collector II Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4739    Accepted Submission(s): 2470 Problem Description The title of this problem is familiar,isn't it?yeah,if you had took pa

hdu 2639 Bone Collector II 01背包问题 求第K大最优值。。

Bone Collector II Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2665    Accepted Submission(s): 1392 Problem Description The title of this problem is familiar,isn't it?yeah,if you had took pa

HDU 2639 Bone Collector II(01背包变型)

此题就是在01背包问题的基础上求所能获得的第K大的价值. 具体做法是加一维去推当前背包容量第0到K个价值,而这些价值则是由dp[j-w[ i ] ][0到k]和dp[ j ][0到k]得到的,其实就是2个数组合并之后排序,但是实际做法最好不要怎么做,因为你不知道总共有多少种,而我们最多只需要前K个大的就行了(因为可能2个数组加起来的组合数达不到K个),如果全部加起来数组开多大不清楚,所以可以选用归并排序中把左右2个有序数组合并成一个有序数组的方法来做,就是用2个变量去标记2个有序数组的头,然后比

Bone Collector II(HDU 2639 DP)

Bone Collector II Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3471    Accepted Submission(s): 1792 Problem Description The title of this problem is familiar,isn't it?yeah,if you had took par

HDU 2639 Bone Collector II

Bone Collector II Time Limit: 2000ms Memory Limit: 32768KB This problem will be judged on HDU. Original ID: 263964-bit integer IO format: %I64d      Java class name: Main The title of this problem is familiar,isn't it?yeah,if you had took part in the

HDU2639 第k小01背包 xingxing在努力

这个题目是求解第k小01背包, 我们只需要再多加一维表示容量为j时的价值即可..代码里面用了归并排序的思想来求解f[j][k], 代码如下: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int f[1000+10][35]; int A[35], B[35]; //A选 B不选 int W[100+10], V[100+10]; int N, v, K; v

第K大01背包

其实这个问题,真的挺好想的,但是我咋想了那么久呢~~ 很好理解,第K大01背包一定基于01背包,dp数组也很容易的想到由dp[V]  ---->   dp[V][K],来表示背包容量是V时候的第K大背包 然后就是状态转移方程了,多写一写,你也能手推出来的,不能被吓到 dp[V][1] = max_第一大(dp[v][1],dp[v-w][1]+vi) dp[V][2] = max_第二大数(dp[v][1],dp[v-w][1]+vi,dp[v][2],dp[v-w][2]+vi) =  max