c++实现0-1背包问题完整源码(动态规划实现)

转自:东风破的博客 http://blog.sina.com.cn/jaydongfengpo

[cpp]  view plain copy
  1. #include   
  2. #define MAX_NUM 5  
  3. #define MAX_WEIGHT 10  
  4. using namespace std;  
  5.   
  6. //动态规划求解  
  7. int zero_one_pack(int total_weight, int w[], int v[], int flag[], int n)  
  8.   int c[MAX_NUM+1][MAX_WEIGHT+1] {0}; //c[i][j]表示前i个物体放入容量为j的背包获得的最大价值  
  9.   // c[i][j] max{c[i-1][j], c[i-1][j-w[i]]+v[i]}  
  10.   //第i件物品要么放,要么不放  
  11.   //如果第i件物品不放的话,就相当于求前i-1件物体放入容量为j的背包获得的最大价值  
  12.   //如果第i件物品放进去的话,就相当于求前i-1件物体放入容量为j-w[i]的背包获得的最大价值  
  13.   for (int 1; <= n; i++)  
  14.     for (int 1; <= total_weight; j++)  
  15.       if (w[i] j)  
  16.         // 说明第i件物品大于背包的重量,放不进去  
  17.         c[i][j] c[i-1][j];  
  18.       else  
  19.         //说明第i件物品的重量小于背包的重量,所以可以选择第i件物品放还是不放  
  20.           if (c[i-1][j] v[i]+c[i-1][j-w[i]])  
  21.             c[i][j] c[i-1][j];  
  22.            
  23.           else  
  24.             c[i][j]  v[i] c[i-1][j-w[i]];  
  25.            
  26.        
  27.      
  28.    
  29.   
  30.   //下面求解哪个物品应该放进背包  
  31.   int n, total_weight;  
  32.   while (c[i][j] != 0)  
  33.     if (c[i-1][j-w[i]]+v[i] == c[i][j])  
  34.       // 如果第i个物体在背包,那么显然去掉这个物品之后,前面i-1个物体在重量为j-w[i]的背包下价值是最大的  
  35.       flag[i] 1;  
  36.       -= w[i];  
  37.       --i;  
  38.      
  39.    
  40.   return c[n][total_weight];  
  41.  
  42.   
  43. //回溯法求解  
  44. int main()  
  45.   int total_weight 10;  
  46.   int w[4] {0, 3, 4, 5};  
  47.   int v[4] {0, 4, 5, 6};  
  48.   int flag[4]; //flag[i][j]表示在容量为j的时候是否将第i件物品放入背包  
  49.   int total_value zero_one_pack(total_weight, w, v, flag, 3);  
  50.   cout << "需要放入的物品如下" << endl;  
  51.   for (int 1; <= 3; i++)  
  52.     if (flag[i] == 1)  
  53.       cout << << "重量为" << w[i] << ", 价值为" << v[i] << endl;  
  54.    
  55.   cout << "总的价值为: " << total_value << endl;  
  56.   return 0;  
  57. }  

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值