动态规划之0-1背包问题
这是最好理解的动态规划
问题描述
对于容纳的总质量为c的背包要求从n个物品中任意选取物品使得最后的总价值最大,对于第i个物品质量为wi价值为vi
问题分析
对于此类问题我们通常采取动态规划(dynamic programming) 即 dp 核心是找到问题的动态转移方程
- 对于每一个物品我们有两种取法,即选择与不选择
- 对于每一次选择我们根据之前的一次情况从中选择出最大的值作为我们的判断
- 为了提高效率我们需要牺牲空间为代价
动态转移方程
如果w i < j m[i][j] = m[i+1][j]>m[i+1][j-w[i]]+v[i]
否则 m[i][j]=m[i+1][j]
代码
#include<iostream>
using namespace std;
#define maxn 10000
#define max(x,y) (x)>(y)?(x):(y)
int w[maxn], v[maxn];//w表示重量 v表示价值
int m[maxn][maxn];//第一个参数当前的物品的取否 第二个参数表述剩余容量
int main()
{
int n,c;//c表示背包的容量
cin >> n>>c;//输入数字n表示数量n个数据
for (int i = 1; i <= n; i++)
{
cin >> w[i];//重量
}
for (int i = 1; i <= n; i++)
{
cin >> v[i];//价值
}
for (int i=n;i>0;i--)//从后往前放置 i 表示商品的编号
{
for (int j = c; j >= 0; j--) //j表示背包的剩余容量
{
//对于当期的价值的公式 m[i][c] j<W[i]
if (w[i] > j )
{
m[i][j] = m[i + 1][j];//装不进去
}
else //当前背包的剩余容纳量可以放入第i个物品
{
//价值判断 放入与不放入的价格比较
m[i][j] = m[i + 1][j] > m[i+1][j - w[i]] + v[i] ? m[i + 1][j] : m[i+1][j - w[i]] + v[i];
}
}
}
cout<<"最大价值是: "<< m[1][c] << endl;
return 0;
}
表格
为了方便大家的理解下面我们根据动态转移方程打表来更加直观的理解这个问题
现在给你一个背包容积为10商品的数量为5个质量分别是2,2,6,5,4价值分别是6,3,5,4,6
- 第一次打表我们从下网上填(怎么样都行为了让大家直观的看我才用的是这种)
商品i\容积j | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | |||||||||||
2 | |||||||||||
3 | |||||||||||
4 | |||||||||||
5 | 0 | 0 | 0 | 0 | 6 | 6 | 6 | 6 | 6 | 6 | 6 |
- 第二次 选取四号商品
商品i\容积j | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | |||||||||||
2 | |||||||||||
3 | |||||||||||
4 | 0 | 0 | 0 | 0 | 6 | 6 | 6 | 6 | 6 | 10 | 10 |
5 | 0 | 0 | 0 | 0 | 6 | 6 | 6 | 6 | 6 | 6 | 6 |
- 第三次 选取三号商品
商品i\容积j | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | |||||||||||
2 | |||||||||||
3 | 0 | 0 | 0 | 0 | 6 | 6 | 6 | 6 | 6 | 10 | 11 |
4 | 0 | 0 | 0 | 0 | 6 | 6 | 6 | 6 | 6 | 10 | 10 |
5 | 0 | 0 | 0 | 0 | 6 | 6 | 6 | 6 | 6 | 6 | 6 |
- 第四次 选取二号商品
商品i\容积j | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | |||||||||||
2 | 0 | 0 | 3 | 3 | 6 | 6 | 9 | 9 | 9 | 10 | 11 |
3 | 0 | 0 | 0 | 0 | 6 | 6 | 6 | 6 | 6 | 10 | 11 |
4 | 0 | 0 | 0 | 0 | 6 | 6 | 6 | 6 | 6 | 10 | 10 |
5 | 0 | 0 | 0 | 0 | 6 | 6 | 6 | 6 | 6 | 6 | 6 |
- 第五次 选取一号商品
商品i\容积j | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | 0 | 0 | 6 | 6 | 9 | 9 | 12 | 12 | 15 | 15 | 15 |
2 | 0 | 0 | 3 | 3 | 6 | 6 | 9 | 9 | 9 | 10 | 11 |
3 | 0 | 0 | 0 | 0 | 6 | 6 | 6 | 6 | 6 | 10 | 11 |
4 | 0 | 0 | 0 | 0 | 6 | 6 | 6 | 6 | 6 | 10 | 10 |
5 | 0 | 0 | 0 | 0 | 6 | 6 | 6 | 6 | 6 | 6 | 6 |
- 由此可见我们选取1号2号5号商品总价值最大而且为15