一共有n个物品,价值为w, 体积为a.
最直观的想法:
假设i(0 <= i <= n)个物品,其体积不能超过j,只要求出f[i][j],就可以推广到f[n][m]那么我们有两种取法:
1. 取前 i-1个物品,体积不超过j
2. 取第i个物品,体积不超过j
现在考虑第二种取法,因为我们要求的是f[i][j], 所以第二种取法并不好算(要是好算,直接就可以算出来了).
可以发现可以将其转化为 留下一个i的位置即,f[i-1][j-a[i]] ,
**因为f[i-1][j- a[i]] ,f[i-1][j] 之前必然遍历过,所以f[i][j] 就可以从已经有的两种状态得出.**
for(int i = 1; i <= n; i++)
{
for(int j = 0; j <=m; j++)
{
f[i][j] = f[i-1][j]; //左边一定有
if(j >= a[i]) f[i][j] = max(f[i][j] , f[ i-1 ][j - a[i]]+ w[i]); //这边不一定有,所以要判断
//关于这里的max,因为每个物品只能取一次, 实际上是 比较f[i-1][j], 与f[ i-1 ][j - a[i]]+w[i]作比较.
//这里跟 完全背包的max 有些许不同
}
}
关于优化的问题,还有点在思考啦, 写一些在之前的疑惑