如题:http://acm.hdu.edu.cn/showproblem.php?pid=2639
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
第k优解是在最里面增加一层 循环,用来记录当前容量1..k的所有解,用a,b数组分别记录2种转移状态a[d]=f[j-c[i]][d]+w[i],b[d]=f[j][d] d(1...k) i(1...n) j(v...c[i])
f[j][d]代表当前j容量背包的第k优解。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define MAXN 102
#define MAXV 1002
#define max(a,b)(a>b?a:b)
int T,N,V,K;
int c[MAXN];
int w[MAXN];
int f[MAXV][32];
int main()
{
// freopen("C:\\1.txt","r",stdin);
scanf("%d",&T);
while(T--)
{
memset(f,0,sizeof(f));
scanf("%d%d%d",&N,&V,&K);
int i,j,k;
for(i=1;i<=N;i++)
scanf("%d",&w[i]);
for(i=1;i<=N;i++)
scanf("%d",&c[i]);
int a[32],b[32];
for(i=1;i<=N;i++)
for(j=V;j>=c[i];j--)
{
for(k=1;k<=K;k++)
{
a[k]=f[j-c[i]][k]+w[i];
b[k]=f[j][k];
}
int x,y,z;
x=y=z=1;
a[k]=b[k]=-1;
while(z<=K&&(x<=K||y<=K))
{
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]);
}
return 0;
}