01背包


 状态转移方程及伪代码的实现和优化(一维数组)
f[i][v] 前i件物品恰放入一个容量为v的背包可以获得的最大价值。
_f[i][v] = max{f[i-1][v],f[i-1][v-c[i]]+w[i]};_
* 若不放第i件物品,则最大价值和放前i-1件物品的价值相同,当前背包的最大价值为f[i][v] = f[i-1][v]
* 若放第i件物品,则最大价值为前i-1件物品的最大价值➕第i件物品的价值 f[i][v] = f[i-1][v-c[i]]+w[i],v-c[i] 表示现在将第i件物品加入到背包中,则前i-1件物品所占的体积应该是总体积-第i个物品所占的体积

//在要装入的物品顺序一定时,背包某一时刻的体积是固定的,可以直接对应背包中装入的物品

for i=1..N //从1到N的物品
for v=V..0 //体积从大到小
//f[v]直接表示在装入第i件物品时,当前背包容积为v时的背包的最大价值
f[v] = max{f[v],f[v-c[i]]+w[i]};

cost——第i件物品的费用
weight ——第i件物品的价值

//调用的子过程:在装入一个费用为cost,价值为weight的物品时,只需要考虑再有足够空间装入这个物品时(v>cost),背包的 状态随着背包的容量改变,在背包处于不同容量时,判断当前的最大价值
procedure ZeroOnePack(cost,weight)
for v=V..cost
f[v] = max{f[v],f[v-cost]+weight}

费用为cost的物品不会影响状态f[0..cost-1]

for i=1..N
ZeroOnePack(c[i],w[i]);

 两种求最优解的背包问题-初始化问题
* 恰好装满背包时的最优解
> f[0] = 0;
> f[1..v] = -无穷
> 只有在容量为0时的最大价值才为合法值,即只有容量为0的背包可能被价值为0的nothing “恰好装满”
* 没有要求必须把背包装满
> 任何容量的背包都有一个合法解表示什么都不装,这个解的价值为0,初始时状态的值全部为0

 对于背包某一状态时容量范围下限的优化
对 for v=V..1的下限优化
假设在装入第i件物品之前,装入了i之后的所有物品,此时背包的容量为V-sum{c[i..n]}
假设此时背包剩余的体积还够装入第i 件物品,也就是背包剩余的容积为c[i]
比较这两种情况哪个剩余的容积更大,更大的为优化后的下限

for i=1..N
for v=V..0
//优化后
for i=1..n
bound = max{V-sum{c[i..n]},c[i]}
for v=V..bound
原文地址:https://www.cnblogs.com/HackHer/p/6159284.html