HDU - 2639 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.
Input
The first line contain a integer T , the number of cases. 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.
Output
One integer per line representing the K-th maximum of the total value (this number will be less than 2 31).
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
题意: 求第k优方案 T组样例 给你 n,m,k 有n组数 m大的背包 求第k优方案 下两行分别是 v 和 W
以前求01背包问题的时候都是求的最优的,这道题是求第k大的也就是说得把过程中的不是最优的也得保留下来
所以把dp开成二维 第二维求第k优方案的决策
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 #include<bits/stdc++.h> 2 #include<cstdio> 3 #include<iostream> 4 #include<cstring> 5 #include<algorithm> 6 using namespace std; 7 const int inf=0x3f3f3f3f; 8 const int st=100000; 9 int dp[1001][40]; 10 int w[1009],v[1009]; 11 int a[1009],b[1009]; 12 int main() 13 { 14 int m,n,k; 15 int t; 16 cin>>t; 17 while(t--) 18 { cin>>n>>m>>k; 19 for(int i=0;i<n;i++) 20 cin>>v[i]; 21 for(int i=0;i<n;i++) 22 cin>>w[i]; 23 memset(dp,0,sizeof(dp)); 24 for(int i=0;i<n;i++) 25 { 26 for(int j=m;j>=w[i];j--) 27 { 28 int kk; 29 for( kk=1;kk<=k;kk++) //k种方案 30 { 31 a[kk]=dp[j][kk]; 32 b[kk]=dp[j-w[i]][kk]+v[i]; 33 34 } 35 a[kk]=b[kk]=-1; 36 int q,w,e; 37 q=w=e=1; 38 while((a[q]!=-1||b[w]!=-1)&&e<=k) //相当于把a b数组合并sort一下保留前面k大的,也就是dp[j] 前k种最优方案 39 { 40 if(a[q]>b[w]) dp[j][e]=a[q],q++; 41 else dp[j][e]=b[w],w++; 42 if(dp[j][e]!=dp[j][e-1]) e++; 43 44 } 45 46 47 } 48 49 50 51 52 53 } 54 cout<<dp[m][k]<<endl; 55 56 } 57 58 return 0; 59 }