01背包问题
题目
有N件物品和一个容量为M的背包,每种物品只可以取一件。第i件物品的费用是c[i],价值是v[i]。求解将哪些物品装入背包可使价值总和最大。
分析
这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放。用子问题定义状态:即f[i][j]表示前i件物品恰放入一个容量为j的背包可以获得的最大价值。则其状态转移方程便是:
f[i][j]=max{f[i-1][j],f[i-1][j-c[i]]+v[i]}
优化空间复杂度
即改用一维数组f[j]存储第i个物品时剩余空间为j时的背包的最大价值。
注意到j-c[i]<j这个关系,当j=0……M顺序推f[j],则后面的到的f[j]将会使用到当前i状态下新生成的f[j-c[i]],而不是我们所需的i-1状态时的f[j-c[i]]。
因此,在每次主循环中我们以j=M……0顺序推f[j],这样才能保证推f[j]时f[j-c[i]]保存的是状态f[i-1][j-c[i]]的值。
参考代码
/*
* n:物品种类 每种只能选取一种
*