01背包问题(动态规划入门)
2017-03-29 17:58
274 查看
01背包问题
给定N种物品和一个背包。物品i的重量是Wi,其价值位Vi ,背包的容量为M。问应该如何选择装入背包的物品,使得转入背包的物品的总价值为最大??
在选择物品的时候,对每种物品i只有两种选择,即装入背包或不装入背包。不能将物品i装入多次,也不能只装入物品的一部分。因此,该问题被称为0-1背包问题。
思路:用V(i,j)表示将前i种物品放入容量为j的背包中能得到的最大价值,则 V(i,0) = V(0,j) = 0。对于第i种物品,有装入和不装入2种情况。当Wi > j时,背包容量不足,只能选择不装入。此时V(i,j) = V(i-1,j)。当Wi <= j时,此时需要统计装入和不装入第i种物品这两种情况下的价值,最后取较大者作为V(i,j)的值。此时V(i,j) = max{V(i-1,j),V(i-1,j-Wi)+Vi}。综上,可以列出状态转换方程为
V(i-1,j) ,Wi > j,1 <= i <= N
V(i,j) = {
max{ V(i-1,j),V(i-1,j-Wi)+Vi } ,Wi <= j <= M,1 <= i <= N
题目描述
有编号分别为a,b,c,d,e的五件物品,它们的重量分别是2,2,6,5,4,它们的价值分别是6,3,5,4,6。现在给你个承重为10的背包,如何让背包里装入的物品具有最大的价值总和?
思路:首先构造一个二维数组V[m]
,m = #{a,b,c,d,e}+1,n = 10+1.然后初始化v[i][0] = v[0][j] = 0(0 <= i < m ,0 <= j < n)。再根据上面的状态转换方程依次填写二维数组的每一个值(按照先填列再填行的顺序),那么二维数组的最后的一个值即是最大的价值总和。
示例代码如下:
运行结果见下图:
给定N种物品和一个背包。物品i的重量是Wi,其价值位Vi ,背包的容量为M。问应该如何选择装入背包的物品,使得转入背包的物品的总价值为最大??
在选择物品的时候,对每种物品i只有两种选择,即装入背包或不装入背包。不能将物品i装入多次,也不能只装入物品的一部分。因此,该问题被称为0-1背包问题。
思路:用V(i,j)表示将前i种物品放入容量为j的背包中能得到的最大价值,则 V(i,0) = V(0,j) = 0。对于第i种物品,有装入和不装入2种情况。当Wi > j时,背包容量不足,只能选择不装入。此时V(i,j) = V(i-1,j)。当Wi <= j时,此时需要统计装入和不装入第i种物品这两种情况下的价值,最后取较大者作为V(i,j)的值。此时V(i,j) = max{V(i-1,j),V(i-1,j-Wi)+Vi}。综上,可以列出状态转换方程为
V(i-1,j) ,Wi > j,1 <= i <= N
V(i,j) = {
max{ V(i-1,j),V(i-1,j-Wi)+Vi } ,Wi <= j <= M,1 <= i <= N
题目描述
有编号分别为a,b,c,d,e的五件物品,它们的重量分别是2,2,6,5,4,它们的价值分别是6,3,5,4,6。现在给你个承重为10的背包,如何让背包里装入的物品具有最大的价值总和?
思路:首先构造一个二维数组V[m]
,m = #{a,b,c,d,e}+1,n = 10+1.然后初始化v[i][0] = v[0][j] = 0(0 <= i < m ,0 <= j < n)。再根据上面的状态转换方程依次填写二维数组的每一个值(按照先填列再填行的顺序),那么二维数组的最后的一个值即是最大的价值总和。
示例代码如下:
#include<iostream> #include<vector> using namespace std; int MaxValueUseDP(int(&wei)[5], int(&val)[5], int limit) { int sz = sizeof(wei) / sizeof(int); int m = sz + 1; int n = limit + 1; int ret = 0; //声明m行n列的二维动态数组 vector<vector<int> >V(m, vector<int>(n)); V.reserve(50); //初始化 for (int i = 0; i < m; ++i) V[i][0] = 0; for (int j = 0; j < n; ++j) V[0][j] = 0; //按先列后行的顺序遍历赋值 for (int j = 1; j < n; ++j) for (int i = 1; i < m; ++i) { if (wei[i-1] > j) V[i][j] = V[i - 1][j]; else { int tmp = V[i - 1][j - wei[i-1]] + val[i-1]; int max = V[i - 1][j] > tmp ? V[i - 1][j] : tmp; V[i][j] = max; } } ret = V[m-1][n-1]; return ret; } int main() { int Wi[5] = { 2,2,6,5,4 }; int Vi[5] = { 6,3,5,4,6 }; int MaxWeight = 10; cout << MaxValueUseDP(Wi, Vi, MaxWeight) << endl; return 0; }说明:被调函数的形参设为含有5个int类型元素数组的引用,限制了传入实参只能是含有5个int类型元素的数组。
运行结果见下图:
相关文章推荐
- 动态规划--01背包问题
- 动态规划 01背包问题
- 动态规划入门之硬币问题
- 动态规划之01背包问题 通俗理解动态规划的过程
- 动态规划—杭电ACM 1203 I NEED A OFFER!(01背包问题)
- 【转】01背包问题动态规划详解
- 动态规划的用法——01背包问题
- 动态规划解决01背包问题
- 动态规划之01背包问题
- 动态规划之01背包问题(最易理解的讲解)
- 【转】01背包问题动态规划详解
- 动态规划入门之01背包
- 动态规划 - 01背包问题
- 动态规划-最长递增子序列/最长公共子序列/01背包问题
- 动态规划--01背包问题
- 0-1背包问题(动态规划入门)
- 动态规划入门三---背包问题(1)
- 动态规划之01背包问题
- 动态规划之01背包问题
- ACM:动态规划,01背包问题