动态规划的用法——01背包问题
2015-01-10 00:00
801 查看
动态规划的用法——01背包问题
Java
问题主题:著名的01背包问题 |
问题描述: 有n个重量和价值分别为wi、vi的物品,现在要从这些物品中选出总重量不超过W的物品,求所有挑选方案中的价值最大值。 限制条件: 1<=N<=100 1<=wi 、vi<=100 1<=wi<=10000 |
样例: 输入 N=4 W = {2, 1, 3, 2} V = {3, 2, 4, 2} 输出 W = 5(选择0,1,3号) |
【解法一】
解题分析:
用普通的递归方法,对每个物品是否放入背包进行搜索程序实现:
C++#include <stdio.h> #include <tchar.h> #include <queue> #include "iostream" using namespace std; const int N = 4; const int W = 5; int weight = {2, 1, 3, 2}; int value = {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++#include <stdio.h> #include <tchar.h> #include <queue> #include "iostream" using namespace std; const int N = 4; const int W = 5; int weight = {2, 1, 3, 2}; int value = {3, 2, 4, 2}; int record [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; } |
package greed; /** * User: luoweifu * Date: 14-1-21 * Time: 下午5:13 */ 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 [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; } } |
算法复杂度:
时间复杂度O(NW)相关文章推荐
- 动态规划的用法——01背包问题
- 动态规划的用法——01背包问题
- 动态规划的用法——01背包问题
- 动态规划--01背包问题
- 01背包问题 很裸的动态规划
- 动态规划之01背包问题(最易理解的讲解)
- 动态规划之01背包问题
- 【转】01背包问题动态规划详解
- 动态规划之01背包问题
- 动态规划解决01背包问题
- 动态规划—杭电ACM Bone Collector(01背包问题)
- Sicily 1146 采药(DP动态规划——01背包问题)
- 【转】01背包问题动态规划详解
- 动态规划之01背包问题 通俗理解动态规划的过程
- 动态规划之01背包问题
- 动态规划—杭电ACM 1203 I NEED A OFFER!(01背包问题)
- 动态规划解决01背包问题
- 动态规划 01背包问题
- 动态规划--01背包问题
- hihoCoder - 1038 - 01背包 (经典动态规划问题!!)