关于01背包的理解
前段时间自学了01背包,但是还有很多地方并不太理解,所以写一篇博客整理一下疑问所在和已经理解的部分。
01背包例题:
有N件物品和一个容量为V的背包。第i件物品的重量是c[i],价值是w[i]。
求解将哪些物品装入背包可使这些物品的重量总和不超过背包容量,且价值总和最大。
洛谷P2871 AC代码以及注释:
#include<cstdio>
#include<iostream>
using namespace std;
struct node//使用结构体存储
{
int c;
int w;
}a[23333];
int n, m, f[23333333];//因为f是记录背包容量的 所以一定要把f数组开到大于总容量
int main()
{
scanf("%d%d", &n, &m);//n是物品数量 m是背包最大容量
for(int i = 1; i <= n; i++) scanf("%d%d", &a[i].c, &a[i].w);
//a[i].c是重量 a[i].w是价值
for(int i = 1; i <= n; i++)//n件物品
{
for(int v = m; v >= a[i].c; v--)
{
//f[v]表示重量不超过v的最大价值
//v>=a[i].c是使得v-a[i].c>=0
//因为小于a[i].c的肯定装不下a[i] 所以不需要计算
//这里通过第一个for循环枚举过了所有物品
//这样就记录出了每件物品放入或者不放入的后果
f[v] = max(f[v], f[v - a[i].c] + a[i].w);
//f[v]:不选的价值;
//f[v-a[i].c]+a[i].w:选择后的价值;
//v-a[i].c:背包中还剩下的空间;
//后面一项的本质就是背包中还剩下的空间所占有的最大价值
//加上a[i].c大小的空间本身所带有的价值
}
}
printf("%d", f[m]);
return 0;
}