第k大值01背包问题

时间:2021-11-03 14:40:01

http://acm.hdu.edu.cn/showproblem.php?pid=2639
/*
第一行输入t 代表t组测试数据
第二行 输入物品个数 背包容量 要求的第k大值
物品的价值
物品的重量

分析:
平常我们用的dp[j]=max(dp[j],dp[j-w[i]]+v[i]);所求的就是最大值 当然在1物品下容量为10的情况下有最大值 次大值
三大值 。。。。。。。。。。。。
很容易想到用dp[][k]二维数组 在当前的容量下第k大值的价值
*/

include

include

include

include

using namespace std;
int dp[1005][50],d1[50];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,m,k;
int w[105],v[105];
memset(dp,0,sizeof(dp));
scanf("%d%d%d",&n,&m,&k);
for(int i=1; i<=n; i++)
scanf("%d",&v[i]);
for(int i=1; i<=n; i++)
scanf("%d",&w[i]);
for(int i=1;i<=n;i++)
for(int j=m;j>=w[i];j--)
{
int count=0;
for(int q=1;q<=k;q++)
{
d1[count++]=dp[j][q];//统统加入一个数组
d1[count++]=dp[j-w[i]][q]+v[i];
}
sort(d1,d1+count);//然后排序就是从最大值到第k大值了
int op=1;
for(int q=count-1;q>=0;q--)
{
if(op>k)break;
if(q==count-1||d1[q]!=d1[q+1])
dp[j][op++]=d1[q];//比如5 5 5 4 3 2 这里面有重复的值 第一个5和第二个5都是最大值 所以去重
}
}
printf("%d\n",dp[m][k]);
}

return 0;

}