认真分析一下题目:
现在用 weight[i] 表示 i物品 的重量,用 value[i] 表示 i物品 的价值。
现有n件物品,还有空间为m的背包。
再用一个数组 a[1025] 记录,
比如: a[2]==1 表示第2件物品放进背包
a[3] ==0 表示第3件物品为放进背包
那么数组a就成为记录物品放还是没发的数字序列
那么题目的约束条件是什么呢?
n∑i=1 welght[i] * a[i] <= m
那结果的要求条件呢?
max( n∑i=1 value[i] * a[i] )
分析下过程:
那么就可以把这个过程看做n次选择,每次选择就两种可能:放或不放?
但在你决定放不放之前,你要想看看这件物品,此时你会碰到两种情况:
1、物品i的占用空间 > 背包剩余空间
那你别纠结了,想放也放不了啊!
pack[i][m] = pack[i-1][m];
2、物品i的占用空间 ≤ 背包剩余空间
这个时候才要考虑放还是不放,不放的话依旧是:pack[i][m] = pack[i-1][m];
放的话就是:pack[i-1][j - weight[i]] + value[i]
当然了,如何最终决策放还是不放?那就看看两个值大了
不过,这个比较取大里面可有门道了,我们需要对pack[n][m]z中的n做循环。
注:pack[i][j] 表示 空间为i是,考虑1到j件物品,最大的收获价值。(只有搞清这个才行)
关键代码:
for(int i=1; i<=n; i++){ // 一件一件地放,n次选择
for(int j=m; j>0; j--){ // 重点代码!!!
if(j >= weight[i]){ // 剩余空间够的话,但要选择放还是不放?
// 所以我们要 “放 VS 不放”,选取最大
// 不放:不变---pack[i-1][j]
// 放:pack[i][j] = pack[i-1][j - weight[i]] + value[i]
pack[i][j] = max(pack[i-1][j] , pack[i-1][j - weight[i]] + value[i]);
}
else{ // 剩余空间不过的话,当然放东西了,所以不变
pack[i][j] = pack[i-1][j];
}
}
}
具体代码查看此处:动态规划问题04_01背包例题与代码