hdu2639(01背包k优解)

来源:互联网 发布:网络交易监管系统 编辑:程序博客网 时间:2024/06/09 03:47

没怎么理解题意,

题意:有n件物品,背包体积为v,给出一行价值和一行花费,求第k优解,每个物品只能取一次。

思路:不考虑k优解,显然是个简单的01背包,1维的数组足够表示。即便要求k优解,在k<=30的条件下,此题再加1维也没什么好说的,用dp[j][k]表示背包体积为j时的k优解,一开始不知道怎么转移,原来无非是记录当前每种可能的解,然后从大到小插进数组就行了。时间复杂度就是o(nvk),最大也就3*10^6。


代码

  1. #include <stdio.h>  
  2. #include <string.h>  
  3. #include <algorithm>  
  4. using namespace std;  
  5.   
  6. struct Node  
  7. {  
  8.     int price;  
  9.     int val;  
  10. } node[1005];  
  11.   
  12. int main()  
  13. {  
  14.     int t;  
  15.     scanf("%d",&t);  
  16.     while(t--)  
  17.     {  
  18.         int n,v,k,i,dp[1005][31] = {0},a[31],b[31];  
  19.         scanf("%d%d%d",&n,&v,&k);  
  20.         for(i = 0; i<n; i++)  
  21.             scanf("%d",&node[i].price);  
  22.         for(i = 0; i<n; i++)  
  23.             scanf("%d",&node[i].val);  
  24.         int j;  
  25.         for(i = 0; i<n; i++)  
  26.         {  
  27.             for(j = v; j>=node[i].val; j--)  
  28.             {  
  29.                 int cnt = 0,d;  
  30.                 for(d = 1; d<=k; d++)//分别将放入第i个石头与不放第i个石头的结果存入a,b,数组之中  
  31.                 {  
  32.                     a[d] = dp[j-node[i].val][d]+node[i].price;  
  33.                     b[d] = dp[j][d];  
  34.                 }  
  35.                 int x,y,z;  
  36.                 x = y = z = 1;  
  37.                 a[d] = b[d] = -1;  
  38.                 while(z<=k && (x<=k || y<=k))//循环找出前K个的最优解  
  39.                 {  
  40.                     if(a[x] > b[y])  
  41.                     {  
  42.                         dp[j][z] = a[x];  
  43.                         x++;  
  44.                     }  
  45.                     else  
  46.                     {  
  47.                         dp[j][z] = b[y];  
  48.                         y++;  
  49.                     }  
  50.                     if(dp[j][z]!=dp[j][z-1])  
  51.                     z++;  
  52.                 }  
  53.             }  
  54.         }  
  55.         printf("%d\n",dp[v][k]);  
  56.     }  
  57.   
  58.     return 0;  
  59. }  

原创粉丝点击