2639-Bone Collector II (01背包之第k优解)

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=2639

求第k优解的关键代码:

用两个数组记录两种状态(选择或不选择),并且只要记录前k次。在这两个数组中都是前k次可能的最优解。所以我们只要把这两个数组做比较,一直排到k就行了

题目代码:

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 int dp[1005][35],a[35],b[35],val[105],vol[105];
 6 int main()
 7 {
 8     int t,n,v,k,c,d,e;
 9     while(~scanf("%d",&t))
10     {
11         while(t--)
12         {
13             scanf("%d%d%d",&n,&v,&k);
14             for(int i=0;i<n;i++)
15             scanf("%d",&val[i]);
16             for(int i=0;i<n;i++)
17             scanf("%d",&vol[i]);
18             memset(dp,0,sizeof(dp));
19             memset(a,0,sizeof(a));
20             memset(b,0,sizeof(b));
21             for(int i=0;i<n;i++)
22             {
23                 for(int j=v;j>=vol[i];j--)
24                 {
25                     for(int t=1;t<=k;t++)
26                     {
27                         a[t]=dp[j-vol[i]][t]+val[i];
28                         b[t]=dp[j][t];
29                     }
30                     c=d=e=1;
31                     while(e<=k&&(c!=k+1||d!=k+1))
32                     {
33                         if(a[c]>b[d])
34                         dp[j][e]=a[c++];
35                         else
36                         dp[j][e]=b[d++];
37                         if(dp[j][e]!=dp[j][e-1])
38                         e++;
39                     }
40                 }
41             }
42             printf("%d\n",dp[v][k]);
43         }
44     }
45     return 0;
46 }

时间: 2024-10-24 10:22:17

2639-Bone Collector II (01背包之第k优解)的相关文章

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个有序数组的头,然后比

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

背包的第k优解[动态规划]

From easthong ☆背包的第k优解                 描述 Description     DD 和好朋友们要去爬山啦!他们一共有 K 个人,每个人都会背一个包.这些包的容量是相同的,都是 V.可以装进背包里的一共有 N 种物品,每种物品都有给定的体积和价值. 在 DD 看来,合理的背包安排方案是这样的: 1. 每个人背包里装的物品的总体积恰等于包的容量.  2. 每个包里的每种物品最多只有一件,但两个不同的包中可以存在相同的物品.  3. 任意两个人,他们包里的物品清单

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

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

HDU2639Bone Collector II[01背包第k优值]

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

hdu2639(背包求第k优解)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2639 题意:给出一行价值,一行体积,让你在v体积的范围内找出第k大的值 分析:dp[i][j][k]表示前i个物品容积为j时的第k优解.那么对于每种状态dp[i][j]都需要维护好前k优解. 每次根据前k优解进行每种取或不取第i件物品,用数组a记录取第i件物品,数组b记录不取,这样 数组a,b了所有能组成j的x种解,最后在x里取前k优解记录下来就好.剩下的肯定不是前k优解了... #include

杭电 2639 Bone Collector II【01背包第k优解】

解题思路:对于01背包的状态转移方程式f[v]=max(f[v],f[v-c[i]+w[i]]);其实01背包记录了每一个装法的背包值,但是在01背包中我们通常求的是最优解, 即为取的是f[v],f[v-c[i]]+w[i]中的最大值,但是现在要求第k大的值,我们就分别用两个数组保留f[v]的前k个值,f[v-c[i]]+w[i]的前k个值,再将这两个数组合并,取第k名. 即f的数组会增加一维. http://blog.csdn.net/lulipeng_cpp/article/details/