动态规划——第一章 背包问题
如果你看过一遍了,点这里
没看过最好看一遍 /滑稽
背景
相信背包问题是很多初学者的噩美梦吧
什么?
你说是?你说不是?
\quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\
没有人比我更懂BAG ——川××
这…
那我问你几个问题,答不上来你就回家去1.3吧哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈
第一题
1. w i 是 什 么 ? W 又 是 什 么 ? 1.w_i是什么?W又是什么? 1.wi是什么?W又是什么?
A.就是wi和W呗 | B.w_i是物品i重量,W是背包容量 | C.w_i是第i个物品的价值,W是最大总价值 | D.不知道
\quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\
第二题
2. v i 是 什 么 ? V 又 是 什 么 ? 2.v_i是什么?V又是什么? 2.vi是什么?V又是什么?
A.就是vi和V呗 | B.v_i是物品i重量,V是背包容量 | C.v_i是第i个物品的价值,V是最大总价值 | D.不知道
\quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\
第三题
3.
这
题
是
用
来
水
的
你
别
在
意
你
都
闯
到
这
里
了
,
休
息
一
下
吧
,
∣
其
实
那
些
题
都
是
水
的
‾
‾
∣
3.这题是用来水的你别在意\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ 你都闯到这里了,休息一下吧,|\overline{\underline{其实那些题都是水的}}|
3.这题是用来水的你别在意你都闯到这里了,休息一下吧,∣其实那些题都是水的∣
点击跳转到1.3(其实是讲解)
\quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\ \quad\\
哈?我也许有点啥也不懂
……阿巴阿巴阿巴阿巴阿巴……怎么可能错呢……阿巴阿巴阿巴阿巴……
这里其实是讲解你信吗我估计你不会信,这,就是讲解
首先,
名词解释
W系列
这还不简单,W不就是WEIGHT的缩写嘛
w i 肯 定 就 是 第 i 个 物 品 的 重 量 辣 , W 不 就 是 背 包 容 量 吗 w_i肯定就是第i个物品的重量辣,W不就是背包容量吗 wi肯定就是第i个物品的重量辣,W不就是背包容量吗
这都不会看我不扇你
V系列
其实根本没有大V,为了凑格式补得 /滑稽
V就是VALUE的缩写
v i 就 是 第 i 个 物 品 的 价 值 辣 v_i就是第i个物品的价值辣 vi就是第i个物品的价值辣
其他
n:物品数量
res[i][w]:结果数组,右下角就是结果
正文
这里是正文正是里这
在经历千辛万苦了解了含义之后,理解就容易多了
首先,你先不知道为什么地列个表格,有(W+1)列(N+1)行
这里,我们设
W为20,n=5,w[]={5,7,8,9,10},v[]={6,8,10,11,12}。
再设处理的函数为bag(int i,int W);
i\W | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | |||||||||||||||||||||
1 | |||||||||||||||||||||
2 | |||||||||||||||||||||
3 | |||||||||||||||||||||
4 | |||||||||||||||||||||
5 |
1.想,你就想
你仔细想想,i=0(即没有物品)、w=0(即背包容量为0)会产生价值吗?当然不会。所以这一行一列可以设为0,也写出了分类的第一步。
i\W | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
1 | 0 | ||||||||||||||||||||
2 | 0 | ||||||||||||||||||||
3 | 0 | ||||||||||||||||||||
4 | 0 | ||||||||||||||||||||
5 | 0 |
b a g [ i , W ] = { 0 i = 0 或 W = 0 . . . bag[i,W]=\begin{cases}\quad\quad\quad0\quad\quad\quad\quad i=0或W=0\\ \quad\quad\quad... \end{cases} bag[i,W]={0i=0或W=0...
2.不够?不够!
你再想,如果这个物品放不下那是不是得和上一个方案(少一个物品)的价值相同?又可以写分类的第二步,但这一步似乎好像不能列表……
b a g [ i , W ] = { 0 i = 0 或 W = 0 b a g [ i − 1 , W ] w [ i ] > W . . . bag[i,W]=\begin{cases}\quad\quad\quad0\quad\quad\quad\quad i=0或W=0\\ \quad bag[i-1,W]\quad\quad w[i]>W\\ \quad\quad\quad... \end{cases} bag[i,W]=⎩⎪⎨⎪⎧0i=0或W=0bag[i−1,W]w[i]>W...
3.普 遍 现 象
还剩最正常的一种情况,但是要使价值最大,要取(不放物品,放物品)的最大价值。
b a g [ i , W ] = { 0 i = 0 或 W = 0 b a g [ i − 1 , W ] w [ i ] > W m a x ( b a g [ i − 1 , W ] , b a g [ i − 1 , W − w [ i ] + v [ i ] ] ) i > 0 且 W > 0 bag[i,W]=\begin{cases}\quad\quad\quad\quad\quad\quad\quad\quad\quad0\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad i=0或W=0\\ \quad\quad\quad\quad\quad\quad\quad\quad bag[i-1,W]\quad\quad\quad\quad\quad\quad\quad\quad w[i]>W\\ max(bag[i-1,W],bag[i-1,W-w[i]+v[i]])\quad i>0且W>0 \end{cases} bag[i,W]=⎩⎪⎨⎪⎧0i=0或W=0bag[i−1,W]w[i]>Wmax(bag[i−1,W],bag[i−1,W−w[i]+v[i]])i>0且W>0
4.做题
把表拷一下,开始,首先,小于一个物品最小重量(5)的的容量(1-4)全部排除。
W为20,n=5,w[]={5,7,8,9,10},v[]={6,8,10,11,12}。
i\W | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 |
2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 8 | 10 | 10 | 10 | 10 | 10 | 10 | 10 | 18 | 18 | 18 | 18 | 18 | 18 |
3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 8 | 10 | 11 | 11 | 11 | 11 | 11 | 11 | 18 | 19 | 21 | 21 | 21 | 21 |
4 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 8 | 10 | 11 | 12 | 12 | 12 | 12 | 12 | 18 | 19 | 21 | 22 | 23 | 23 |
5 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 8 | 10 | 11 | 12 | 12 | 12 | 12 | 12 | 18 | 19 | 21 | 22 | 23 | 23 |
由此得出最大价值为23。
代码
#include <bits/stdc++.h>
using namespace std;
int n,W;
int v[100],w[100];
int res[100][1000];
void bag()
{
for(int i=1; i<=n; i++)
for(int ww=1; ww<=W; ww++)
if(w[i]>ww)
res[i][ww]=res[i-1][ww];
else
res[i][ww]=max(res[i-1][ww],res[i-1][ww-w[i]]+v[i]);
}
int main()
{
cout<<"请输入物品个数及背包容量:\n";
cin>>n>>W;
cout<<"请输入各个物品的重量:\n";
for(int i=0; i<n; i++)
cin>>w[i];
cout<<"请输入各个物品的价值:\n";
for(int i=0; i<n; i++)
cin>>v[i];
bag();
cout<<"res数组:\n";
for(int ww=0; ww<=W; ww++)
{
for(int i=0; i<=n; i++)
cout<<res[i][ww]<<" ";
cout<<endl;
}
return 0;
}