您的位置:首页 > 其它

hdu 2639 Bone Collector II(01背包求第k优解)

2015-10-13 23:38 423 查看
题目地址

题目大意:01背包让求第k优解

解题思路:dp[j][k]表示容量为j的背包的第k优解的值,将01背包的最优解中的max值,每次容量都记录下来(用2个数组来分别存放放当前物品的值和不放当前物品的值),再来合并求第k优解,注意过程中一定要将2个记录数组的k+1个解记为-1,处理其中一个数组先用完的情况

#include <bits/stdc++.h>

using namespace std;

const int maxn = 1000+100;
const int maxm = 100+10;

int val[maxm],vol[maxm],dp[maxn][50],a[50],b[50];

int main()
{
int t,n,v,k;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&n,&v,&k);
for(int i = 1; i <= n; i++)//质量
scanf("%d",&val[i]);
for(int i = 1; i <= n; i++)//体积
scanf("%d",&vol[i]);
if(!k)
{
puts("0");
continue;
}
memset(dp,0,sizeof(dp));
for(int i = 1; i <= n; i++)//n个数
{
for(int j = v; j >= vol[i]; j--)//枚举体积
{
//dp[j] = max(dp[j],dp[j-vol[i]]+val[i]);--01背包
for(int l = 1; l <= k; l++)//k个解
{
a[l] = dp[j][l];//容量为j的第l个解
b[l] = dp[j-vol[i]][l]+val[i];
}
int cnt,r,s;
r = s = cnt = 1;
a[k+1] = b[k+1] = -1;//一定要有,以防a、b先比较完
while(cnt<=k && (s<=k || r<=k))
{
if(a[s]>b[r])
{
dp[j][cnt] = a[s];
s++;
}
else
{
dp[j][cnt] = b[r];
r++;
}
if(dp[j][cnt] != dp[j][cnt-1] || cnt == 1)
cnt++;
}
}
}
printf("%d\n",dp[v][k]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: