算法导论16.2-2
来源:互联网 发布:淘宝丝袜买家秀 编辑:程序博客网 时间:2024/06/13 22:52
- 问题描述
设计动态规划算法求解0-1背包问题,要求运行时间为O(nW) ,n 为商品数,W 是小偷能放进背包的最大商品总重量。0-1背包问题用公式表示为:maximize∑i=1nvixisubjectto∑i=1nwixi≤Wxi∈{0,1}
其中vi 是商品的价值,wi 是商品的重量,W 是背包的容量。 - 一个递归解
假设V[i,j] :总重量不超过j 的前提下,前i 种商品总价值的最大值。显然,当i 或j 有一个为0,那么V[i,j]=0 。当i≠0 且j≠0 时,V[i,j] 的求解可以由它的子问题给出:①若j≥w[i] ,则求解V[i,j] 时可以选第i 件商品对应的最大价值为v[i]+V[i−1,j−w[i]] (此时的最大值取决于在总重量不超过j−w[i] 的前提下,前i−1 种商品总价值的最大值。);也可以不选择第i 件商品,对应的最大价值为V[i−1,j] (此时的最大值即是在总重量不超过j 的前提下,前i−1 种商品总价值的最大值。)。②若j<w[i] ,不能选择第i 件商品,此时所选商品的最大价值即在总重量不超过j 的前提下,前i−1 种商品总价值的最大值V[i−1,j] 。综上可得如下递归式:V[i,j]=⎧⎩⎨⎪⎪0初始条件max{V[i−1,j],v[i]+V[i−1,j−w[i]]}若j≥w[i]V[i−1,j]若j<w[i] - 求解商品的最大价值
为了跟踪所选的商品,用B[i,j] 表示在j 的限制下从前i 件商品中构造的最优解是否含有商品i 。
设计算法的伪代码如下:
KNAPSACK-BST(v,w)
for i=0 to n V[i,0]=0for j=1 to W V[0,j]=0for i=1 to n for j=1 to W if j-w[i]>=0 if V[i-1,j]>(v[i]+V[i-1,j-w[i]]) V[i,j]=V[i-1,j] else V[i,j]=v[i]+V[i-1,j-w[i]] B[i,j]=1 else V[i,j]=V[i-1,j]return V[n,W]
- 构造最优解
PRINT-KNAPSACK(i,j)
if i=0 or j=0 returnif B[i,j]==1 print "Item" i PRINT-KNAPSACK(i-1,j-w[i])else PRINT-KNAPSACK(i-1,j)
- C++实现
#include<iostream>#include<string>#include<algorithm>#define NUM 50#define INT 65536using namespace std;int W;int v[NUM];int w[NUM];int V[NUM][NUM];int B[NUM][NUM];int KNAPSACK_BST(int n){ for (int i = 0; i <= n; i++) V[i][0] = 0; for (int j = 1; j <= W; j++) V[0][j] = 0; for (int i = 1; i <= n; i++){ for (int j = 1; j <= W; j++){ if (j - w[i] >= 0){ if (V[i - 1][j] > (v[i] + V[i - 1][j - w[i]])) V[i][j] = V[i - 1][j]; else{ V[i][j] = v[i] + V[i - 1][j - w[i]]; B[i][j] = 1; } } else V[i][j] = V[i - 1][j]; } } return V[n][W];}void PRINT_KNAPSACK(int i, int j){ if (i == 0 || j == 0) return; if (B[i][j] == 1){ cout << "Item" << i << " "; PRINT_KNAPSACK(i - 1, j - w[i]); } else PRINT_KNAPSACK(i - 1, j);}void main(){ int n; cin >> n; for (int i = 1; i <= n; i++) cin >> v[i]; for (int j = 1; j <= n; j++) cin >> w[j]; cin >> W; cout << KNAPSACK_BST(n) << endl; PRINT_KNAPSACK(n, W); cout << endl;}
输入样例
i123v60100120w102030W=3
输出结果
阅读全文
0 0
- 算法导论16.2-2
- 算法导论-16.2-6
- 算法导论16.2-6
- 算法导论16.2-1
- 算法导论16.2-5
- 算法导论 2-2
- 算法导论学习2
- 算法导论 24-2
- 算法导论 5.1-2
- 算法导论5.4-2
- 算法导论5.4-2
- 算法导论读书笔记2
- 算法导论 5.1-2
- 算法导论22.4-2
- 算法导论1.1-2
- 算法导论 1.2-2
- 算法导论 1.2-2
- 算法导论 2.1-2
- 员工信息管理系统(c++继承)
- 【UML 建模】在线UML建模工具 ProcessOn 使用详解
- 51单片机学习随笔(3)
- StreamToString
- 安卓okhttp的常见用法
- 算法导论16.2-2
- 07_Java基础语法_第7天(练习)
- 【排序】1.3快速排序
- 封装OkHttp工具类
- ImageLoaderjiand简单使用
- 实验报告(暂存)
- 1350:面朝大海 春暖花开 [ 基础版 ]
- AndroidStudio意外关闭,报红提示SetupJDK解决方法
- Hibernate4学习记录三(HibernateUtils工具类设计)