Bone Collector II
题目链接: HDU - 263901背包的第k优解问题, 通常情况下我们只选择最优解, 而摒弃其他解, 现在则需要保留那些非最优解, 最后找到第k优解;
用两个数组保存所有解, 然后不断更新;
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <string.h>
using namespace std;
int dp[1100][40], val[110], vol[110], a[40], b[40];
int main(){
int T;
scanf("%d", &T);
while(T--){
int N, V, K;
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]);
}
memset(dp, 0, sizeof(dp));
for(int i=1; i<=N; i++){
for(int j=V; j>=vol[i]; j--){
for(int k=1; k<=K; k++){
a[k]=dp[j][k];
b[k]=dp[j-vol[i]][k]+val[i];
}
int k, x, y;
x=y=k=1;
a[K+1]=b[K+1]=-1;
while(k!=K+1&&(a[x]!=-1||b[x]!=-1)){
if(a[x]>=b[y]) dp[j][k]=a[x++];
else dp[j][k]=b[y++];
if(dp[j][k]!=dp[j][k-1]) k++;
}
}
}
printf("%d\n", dp[V][K]);
}
return 0;
}