在裸01背包中 状态转移方程为 f[i][v]=max{f[i-1][v] , f[i-1][v-c[i]]+w[i]};
其空间复杂度为O(N*V)很多时候往往会导致堆空间不够,离散化数据来处理这个问题也不方便。
故而若我们能保证
第i次循环结束后f[v]中表示的就是我们定义的状态f[i][v]呢,即在
第次循环时 f[v]=f[i][v]
又由于f[i][v]是由f[i-1][v]和f[i-1][v-c[i]]两个子问题递推而来,故而在推f[i][v]时(也即在第i次主循环中推f[v]时)要能够得到f[i-1][v]和f[i-1][v-c[i]]的值
这要求在每次主循环中我们以v=V..0的顺序推f[v],这样才能保证推f[v]时f[v-c[i]]保存的是状态f[i-1][v-c[i]]的值,即每次进入第二层循环时,被子问题f[v-c[i]]与f[v]都保存的是上个循环即i=i-1时候的值
故而又有f[i][v]=max{f[i-1][v] , f[i-1][v-c[i]]+w[i]};
//伪代码
for i=1..N
for v=V..0
f[v]=max{f[v],f[v-c[i]]+w[i]};
//巧妙的将第二场循环逆过来 似的子问题是最近一次的解
将二维数组的空间变为一维,解决了MLE的问题
顺带一提 若正过来 是无限背包的情况 可以参考下一篇题解