您的位置:首页 > 其它

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

2013-07-16 11:06 127 查看
在求dp[i][j]的最优值的时候,我们比较了两个值的大小,一个是dp[i][j],一个是dp[i][j-b[i]]+a[i],之前我们直接抛弃掉其中一个,留下另一个就是dp[i][j],现在我们不将其抛弃,而是将其记录。准确的说我们以前比较dp[i][j]和dp[i][j-b[i]]+a[i],从中求出第一名,现在我们比较的是dp[i][j][1...K]和dp[i][j-b[i]][1...k]+a[i],从中求出前K名。

思路:分别记录 dp[i][j] 中前K个解,和 dp[i][j-b[i]]+a[i] 中前K个解,那么从两个最有K个解中找出前K个解,这样就得到要求的第K个最优解。

注意:因为题目认为如果两个值相同,无论组合方式如何,都认为是一种情况,所以维护数组是要注意去掉值相同的。

#include<stdio.h>
#include<string.h>
int a[105],c[105],b[105],d[105],f[1005][35];
int main()
{
int t,n,V,K;
int i,j,tt;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&n,&V,&K);
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
for(i=1;i<=n;i++)
scanf("%d",&c[i]);
memset(f,0,sizeof(f));
for(i=1;i<=n;i++)
{
for(j=V;j>=c[i];j--)
{
for(tt=1;tt<=K;tt++)
{
b[tt]=f[j][tt];
d[tt]=f[j-c[i]][tt]+a[i];
}
b[tt]=d[tt]=-1;
int x,y,z;
x=y=z=1;
while(z<=K&&(y<=K||x<=K))
{
if(b[x]>d[y])
f[j][z]=b[x++];
else
f[j][z]=d[y++];
if(f[j][z]!=f[j][z-1])
z++;
}
}
}
printf("%d\n",f[V][K]);
}
return 0;
}
/*
3
5 10 2
1 2 3 4 5
5 4 3 2 1
5 10 12
1 2 3 4 5
5 4 3 2 1
5 10 16
1 2 3 4 5
5 4 3 2 1
*/


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: