生活随笔
收集整理的这篇文章主要介绍了
动态规划的用法——01背包问题
小编觉得挺不错的,现在分享给大家,帮大家做个参考.
动态规划的用法——01背包问题
| 问题主题:著名的01背包问题 |
| 问题描述: 有n个重量和价值分别为wi、vi的物品,现在要从这些物品中选出总重量不超过W的物品,求所有挑选方案中的价值最大值。 限制条件: 1<=N<=100 1<=wi 、vi<=100 1<=wi<=10000 |
| 样例: 输入 N=4 W[N] = {2, 1, 3, 2} V[N] = {3, 2, 4, 2} 输出 W = 5(选择0,1,3号) |
【解法一】
解题分析:
用普通的递归方法,对每个物品是否放入背包进行搜索
程序实现:
C++
| [cpp] view plaincopyprint? #include <stdio.h> #include <tchar.h> #include <queue> #include "iostream" using namespace std; const int N = 4; const int W = 5; int weight[N] = {2, 1, 3, 2}; int value[N] = {3, 2, 4, 2}; int solve(int i, int residue) { int result = 0; if(i >= N) return result; if(weight[i] > residue) result = solve(i+1, residue); else { result = max(solve(i+1, residue), solve(i+1, residue-weight[i]) + value[i]); } } int main() { int result = solve(0, W); cout << result << endl; return 0; } |
【解法二】
解题分析:
用记录结果再利用的动态规划的方法,上面用递归的方法有很多重复的计算,效率不高。我们可以记录每一次的计算结果,下次要用时再直接去取,以提高效率
程序实现:
C++
| [cpp] view plaincopyprint? #include <stdio.h> #include <tchar.h> #include <queue> #include "iostream" using namespace std; const int N = 4; const int W = 5; int weight[N] = {2, 1, 3, 2}; int value[N] = {3, 2, 4, 2}; int record[N][W]; void init() { for(int i = 0; i < N; i ++) { for(int j = 0; j < W; j ++) { record[i][j] = -1; } } } int solve(int i, int residue) { if(-1 != record[i][residue]) return record[i][residue]; int result = 0; if(i >= N) return result; if(weight[i] > residue) { record[i + 1][residue] = solve(i+1, residue); } else { result = max(solve(i+1, residue), solve(i+1, residue-weight[i]) + value[i]); } return record[i + 1][residue] = result; } int main() { init(); int result = solve(0, W); cout << result << endl; return 0; } |
Java
| [java] view plaincopyprint? package greed; public class Knapsack { private int maxWeight; private int[][] record; private Stuff[] stuffs; public Knapsack(Stuff[] stuffs, int maxWeight) { this.stuffs = stuffs; this.maxWeight = maxWeight; int n = stuffs.length + 1; int m = maxWeight+1; record = new int[n][m]; for(int i = 0; i < n; i ++) { for(int j = 0; j < m; j ++) { record[i][j] = -1; } } } public int solve(int i, int residue) { if(record[i][residue] > 0) { return record[i][residue]; } int result; if(i >= stuffs.length) { return 0; } if(stuffs[i].getWeight() > residue) { result = solve(i + 1, residue); } else { result = Math.max(solve(i + 1, residue), solve(i + 1, residue - stuffs[i].getWeight()) + stuffs[i].getValue()); } record[i][residue] = result; return result; } public static void main(String args[]) { Stuff stuffs[] = { new Stuff(2, 3), new Stuff(1, 2), new Stuff(3, 4), new Stuff(2, 2) }; Knapsack knapsack = new Knapsack(stuffs, 5); int result = knapsack.solve(0, 5); System.out.println(result); } } class Stuff{ private int weight; private int value; public Stuff(int weight, int value) { this.weight = weight; this.value = value; } int getWeight() { return weight; } void setWeight(int weight) { this.weight = weight; } int getValue() { return value; } void setValue(int value) { this.value = value; } } |
总结
以上是生活随笔为你收集整理的动态规划的用法——01背包问题的全部内容,希望文章能够帮你解决所遇到的问题。
如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。