1. 程式人生 > >c++實現0-1揹包問題完整原始碼(動態規劃實現)

c++實現0-1揹包問題完整原始碼(動態規劃實現)

轉自:東風破的部落格 http://blog.sina.com.cn/jaydongfengpo

  1. #include 
  2. #define MAX_NUM 5
  3. #define MAX_WEIGHT 10
  4. usingnamespace std;  
  5. //動態規劃求解
  6. int zero_one_pack(int total_weight, int w[], int v[], int flag[], int n) {  
  7.   int c[MAX_NUM+1][MAX_WEIGHT+1] = {0}; //c[i][j]表示前i個物體放入容量為j的揹包獲得的最大價值
  8.   // c[i][j] = max{c[i-1][j], c[i-1][j-w[i]]+v[i]}
  9.   //第i件物品要麼放,要麼不放
  10.   //如果第i件物品不放的話,就相當於求前i-1件物體放入容量為j的揹包獲得的最大價值
  11.   //如果第i件物品放進去的話,就相當於求前i-1件物體放入容量為j-w[i]的揹包獲得的最大價值
  12.   for (int i = 1; i <= n; i++) {  
  13.     for (int j = 1; j <= total_weight; j++) {  
  14.       if (w[i] > j) {  
  15.         // 說明第i件物品大於揹包的重量,放不進去
  16.         c[i][j] = c[i-1][j];  
  17.       } else {  
  18.         //說明第i件物品的重量小於揹包的重量,所以可以選擇第i件物品放還是不放
  19.           if (c[i-1][j] > v[i]+c[i-1][j-w[i]]) {  
  20.             c[i][j] = c[i-1][j];  
  21.           }  
  22.           else {  
  23.             c[i][j] =  v[i] + c[i-1][j-w[i]];  
  24.           }  
  25.       }  
  26.     }  
  27.   }  
  28.   //下面求解哪個物品應該放進揹包
  29.   int i = n, j = total_weight;  
  30.   while (c[i][j] != 0) {  
  31.     if (c[i-1][j-w[i]]+v[i] == c[i][j]) {  
  32.       // 如果第i個物體在揹包,那麼顯然去掉這個物品之後,前面i-1個物體在重量為j-w[i]的揹包下價值是最大的
  33.       flag[i] = 1;  
  34.       j -= w[i];  
  35.       --i;  
  36.     }  
  37.   }  
  38.   return c[n][total_weight];  
  39. }  
  40. //回溯法求解
  41. int main() {  
  42.   int total_weight = 10;  
  43.   int w[4] = {0, 3, 4, 5};  
  44.   int v[4] = {0, 4, 5, 6};  
  45.   int flag[4]; //flag[i][j]表示在容量為j的時候是否將第i件物品放入揹包
  46.   int total_value = zero_one_pack(total_weight, w, v, flag, 3);  
  47.   cout << "需要放入的物品如下" << endl;  
  48.   for (int i = 1; i <= 3; i++) {  
  49.     if (flag[i] == 1)  
  50.       cout << i << "重量為" << w[i] << ", 價值為" << v[i] << endl;  
  51.   }  
  52.   cout << "總的價值為: " << total_value << endl;  
  53.   return 0;  
  54. }