【算法】动态规划的用法——01背包问题

动态规划的用法——01背包问题

 

问题主题:著名的01背包问题

问题描述:

n个重量和价值分别为wivi的物品,现在要从这些物品中选出总重量不超过W的物品,求所有挑选方案中的价值最大值。

限制条件:

1<=N<=100

1<=wvi<=100

1<=wi<=10000

样例:

输入

N=4

W[N] = {2, 1, 3, 2}

V[N] = {3, 2, 4, 2}

输出

W = 5(选择013)

 

 

【解法一】


解题分析:

    用普通的递归方法,对每个物品是否放入背包进行搜索

程序实现:

C++

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #include <stdio.h>  
  2. #include <tchar.h>  
  3. #include <queue>  
  4. #include "iostream"  
  5.    
  6. using namespace std;  
  7.    
  8. const int N = 4;  
  9. const int W = 5;  
  10. int weight[N] = {2, 1, 3, 2};  
  11. int value[N] = {3, 2, 4, 2};  
  12. int solve(int i, int residue)   
  13. {  
  14. int result = 0;  
  15. if(i >= N)  
  16. return result;  
  17. if(weight[i] > residue)  
  18. result = solve(i+1, residue);  
  19. else   
  20. {  
  21. result = max(solve(i+1, residue), solve(i+1, residue-weight[i]) + value[i]);  
  22. }  
  23.    
  24. }  
  25.    
  26. int main() {  
  27. int result = solve(0, W);  
  28. cout << result << endl;  
  29. return 0;  
  30. }  

 

 

【解法

解题分析:

    用记录结果再利用的动态规划的方法,上面用递归的方法有很多重复的计算,效率不高。我们可以记录每一次的计算结果,下次要用时再直接去取,以提高效率

程序实现:

C++

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #include <stdio.h>  
  2. #include <tchar.h>  
  3. #include <queue>  
  4. #include "iostream"  
  5.   
  6. using namespace std;  
  7.   
  8. const int N = 4;  
  9. const int W = 5;  
  10. int weight[N] = {2, 1, 3, 2};  
  11. int value[N] = {3, 2, 4, 2};  
  12. int record[N][W];  
  13. void init()  
  14. {  
  15.     for(int i = 0; i < N; i ++)  
  16.     {  
  17.         for(int j = 0; j < W; j ++)   
  18.         {  
  19.             record[i][j] = -1;  
  20.         }  
  21.     }  
  22. }  
  23.   
  24. int solve(int i, int residue)   
  25. {  
  26.     if(-1 != record[i][residue])  
  27.         return record[i][residue];  
  28.     int result = 0;  
  29.     if(i >= N)  
  30.         return result;  
  31.     if(weight[i] > residue)  
  32.     {  
  33.         record[i + 1][residue] = solve(i+1, residue);  
  34.           
  35.     }  
  36.     else   
  37.     {  
  38.         result = max(solve(i+1, residue), solve(i+1, residue-weight[i]) + value[i]);  
  39.     }  
  40.     return record[i + 1][residue] = result;  
  41. }  
  42.   
  43. int main() {  
  44.     init();  
  45.     int result = solve(0, W);  
  46.     cout << result << endl;  
  47.     return 0;  
  48. }  

Java

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. package greed;  
  2.   
  3. /** 
  4.  * User: luoweifu 
  5.  * Date: 14-1-21 
  6.  * Time: 下午5:13 
  7.  */  
  8. public class Knapsack {  
  9.     private int maxWeight;  
  10.     private int[][] record;  
  11.     private Stuff[] stuffs;  
  12.   
  13.     public Knapsack(Stuff[] stuffs, int maxWeight) {  
  14.         this.stuffs = stuffs;  
  15.         this.maxWeight = maxWeight;  
  16.         int n = stuffs.length + 1;  
  17.         int m = maxWeight+1;  
  18.         record = new int[n][m];  
  19.         for(int i = 0; i < n; i ++) {  
  20.             for(int j = 0; j < m; j ++) {  
  21.                 record[i][j] = -1;  
  22.             }  
  23.         }  
  24.     }  
  25.     public int solve(int i, int residue) {  
  26.         if(record[i][residue] > 0) {  
  27.             return record[i][residue];  
  28.         }  
  29.         int result;  
  30.         if(i >= stuffs.length) {  
  31.             return 0;  
  32.         }  
  33.         if(stuffs[i].getWeight() > residue) {  
  34.             result = solve(i + 1, residue);  
  35.         } else {  
  36.             result = Math.max(solve(i + 1, residue),  
  37.                  solve(i + 1, residue - stuffs[i].getWeight()) + stuffs[i].getValue());  
  38.         }  
  39.         record[i][residue] = result;  
  40.         return result;  
  41.     }  
  42.   
  43.     public static void main(String args[]) {  
  44.         Stuff stuffs[] = {  
  45.             new Stuff(23),  
  46.             new Stuff(12),  
  47.             new Stuff(34),  
  48.             new Stuff(22)  
  49.         };  
  50.         Knapsack knapsack = new Knapsack(stuffs, 5);  
  51.         int result = knapsack.solve(05);  
  52.         System.out.println(result);  
  53.     }  
  54. }  
  55.   
  56. class Stuff{  
  57.     private int weight;  
  58.     private int value;  
  59.   
  60.     public Stuff(int weight, int value) {  
  61.         this.weight = weight;  
  62.         this.value = value;  
  63.     }  
  64.   
  65.     int getWeight() {  
  66.         return weight;  
  67.     }  
  68.   
  69.     void setWeight(int weight) {  
  70.         this.weight = weight;  
  71.     }  
  72.   
  73.     int getValue() {  
  74.         return value;  
  75.     }  
  76.   
  77.     void setValue(int value) {  
  78.         this.value = value;  
  79.     }  
  80. }  
原文链接
 
 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值