Bone Collector II
Here is the link: http://acm.hdu.edu.cn/showproblem.php?pid=2602
Today we are not desiring the maximum value of bones,but the K-th maximum value of the bones.NOTICE that,we considerate two ways that get the same value of bones are the same.That means,it will be a strictly decreasing sequence from the 1st maximum , 2nd maximum .. to the K-th maximum.
If the total number of different values is less than K,just ouput 0.
Followed by T cases , each case three lines , the first line contain two integer N , V, K(N <= 100 , V <= 1000 , K <= 30)representing the number of bones and the volume of his bag and the K we need. And the second line contain N integers representing the value of each bone. The third line contain N integers representing the volume of each bone.
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
12 2 0
01背包的变形体,这次不是让背包的容量最大了,是要求出给定的第K大
我不是很理解,大概意思就是说,把每一种容量的背包的前K种方法都写出来!
下面是我借鉴的别人的解释:
题意:给出一行价值,一行体积,让你在v体积的范围内找出第k大的值.......(注意,不要 和它的第一题混起来,它第一行是价值,再是体积)
思路:首先dp[i][j]代表的是在体积为i的时候第j优解为dp[i][j]......那么,我们就可以这样思考,i对应体积,那么如果只是一维的dp[i],代表的应该是体积为i时的最大值,那么同理,dp[i][1]代表的是体积为i时的最大值,那么我们就可以退出两种动态,dp[i][m],dp[i-s[i][0]][m]+s[i][1].....然后把这两种状态开个两个数组分别保存起来,再合并出体积为i时的前k优解......依次后推,直到dp[v][k].......
下面代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int f[1010][33];
int main()
{
int N,i,j,v,n,k,val[110],vol[110];
scanf("%d",&N);
while(N--)
{
scanf("%d%d%d",&n,&v,&k);
for(i=0;i<n;i++)
scanf("%d",&val[i]);
for(i=0;i<n;i++)
scanf("%d",&vol[i]);
memset(f,0,sizeof(f));
int a[50],b[50],kk;
for(i=0;i<n;i++)
for(j=v;j>=vol[i];j--)
{
for(kk=0;kk<k;kk++)
{
a[kk]=f[j-vol[i]][kk]+val[i];
b[kk]=f[j][kk];
}
a[k]=b[k]=-1;
int x=0,y=0,z=0;
while(z<k&&(a[x]!=-1||b[y]!=-1))
{
if(a[x]>b[y])
f[j][z]=a[x++];
else
f[j][z]=b[y++];
if(f[j][z]!=f[j][z-1])
z++;
}
}
printf("%d\n",f[v][k-1]);
}
return 0;
}
545



被折叠的 条评论
为什么被折叠?



