题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=2639
求第k优解的关键代码:
用两个数组记录两种状态(选择或不选择),并且只要记录前k次。在这两个数组中都是前k次可能的最优解。所以我们只要把这两个数组做比较,一直排到k就行了
题目代码:
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 int dp[1005][35],a[35],b[35],val[105],vol[105]; 6 int main() 7 { 8 int t,n,v,k,c,d,e; 9 while(~scanf("%d",&t)) 10 { 11 while(t--) 12 { 13 scanf("%d%d%d",&n,&v,&k); 14 for(int i=0;i<n;i++) 15 scanf("%d",&val[i]); 16 for(int i=0;i<n;i++) 17 scanf("%d",&vol[i]); 18 memset(dp,0,sizeof(dp)); 19 memset(a,0,sizeof(a)); 20 memset(b,0,sizeof(b)); 21 for(int i=0;i<n;i++) 22 { 23 for(int j=v;j>=vol[i];j--) 24 { 25 for(int t=1;t<=k;t++) 26 { 27 a[t]=dp[j-vol[i]][t]+val[i]; 28 b[t]=dp[j][t]; 29 } 30 c=d=e=1; 31 while(e<=k&&(c!=k+1||d!=k+1)) 32 { 33 if(a[c]>b[d]) 34 dp[j][e]=a[c++]; 35 else 36 dp[j][e]=b[d++]; 37 if(dp[j][e]!=dp[j][e-1]) 38 e++; 39 } 40 } 41 } 42 printf("%d\n",dp[v][k]); 43 } 44 } 45 return 0; 46 }