这题的主要思路是,每一次状态转移都用两个数组将所有可能成为新状态前k优解的值都保存下来,然后对这两个数组进行排序,再得出这两个数组的前k优解,作为新状态。
Bone Collector IITime Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 6930 Accepted Submission(s): 3678 Problem Description The title of this problem is familiar,isn't it?yeah,if you had took part in the "Rookie Cup" competition,you must have seem this title.If you haven't seen it before,it doesn't matter,I will give you a link:
Input The first line contain a integer T , the number of cases.
Output One integer per line representing the K-th maximum of the total value (this number will be less than 231).
Sample Input 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
Sample Output 12 2 0 |
#include<iostream>
#include<string.h>
#include<iomanip>
#include<algorithm>
using namespace std;
int volume[105];
int value[105];
int dp[100001][35];
int main(){
int T;
cin>>T;
while(T--){
int N,V,K;
cin>>N>>V>>K;
memset(volume,0,sizeof(volume));
memset(value,0,sizeof(value));
memset(dp,0,sizeof(dp));
int index=0;
for(int i=1;i<=N;i++){
cin>>value[i];
}
for(int i=1;i<=N;i++){
cin>>volume[i];
}
int a[35]={0};
int b[35]={0};
for(int i=1;i<=N;i++){
for(int j=V;j>=volume[i];j--){
int k;
for( k=1;k<=K;k++){
a[k]=dp[j][k];
b[k]=dp[j-volume[i]][k]+value[i];
}
a[k]=-1;
b[k]=-1;
int ai=1;
int bi=1;
int ci=1;
for(ci=1;ci<=K&&(a[ai]!=-1||b[bi]!=-1);){
if(a[ai]>=b[bi]){
dp[j][ci]=a[ai];
ai++;
} else{
dp[j][ci]=b[bi];
bi++;
}
if(dp[j][ci]!=dp[j][ci-1]){
ci++;
}
}
}
}
cout<<dp[V][K]<<endl;
}
}