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
",dp[v][k]);
43         }
44     }
45     return 0;
46 }
View Code
原文地址:https://www.cnblogs.com/wang-ya-wei/p/5754571.html