榨取kkksc03 多维dp
榨取kkksc03 多维dp
一道简单的动态规划,背包再加一维费用,首先可以易得三维动态规划转移方程
\[dp[i][j][w]=\left\{
\begin{array}{}
max(dp[i-1][j][w], dp[i-1][j-a[i].m][w-a[i].t]+1) \qquad \\
dp[i-1][j][w]
\end{array}
\right.
\]
即当前状态(决策到第\(i\)件物品,已花费\(j\)金钱\(w\)时间)可以由不选这个物品的状态与选了这个物品(如果可以转移)转移而来,其中价值就是已选了多少个物品
而后,类比背包,我们又可以去掉第一维,将三维压到二维。当然,也同背包,\(j\)和\(w\)的遍历应为倒序。
核心代码:
for(int i=1;i<=n;i++)
for(int j=m;j>=0;j--)
for(int w=t;w>=0;w--)
if(j-a[i].m>=0&&w-a[i].t>=0)//判断状态是否合法
f[j][w]=MAX(f[j][w], f[j-a[i].m][w-a[i].t]+1);
else
f[j][w]=f[j][w];
然而需要注意的是:
- 状态转移时要注意其合法性
- 初始化要均初始化为0。因为这样才能使最终
f[m][t]
的值表示不一定填满[m][n]
的背包所获得的最大价值(因为最优解可能没有填满背包,即未用尽金钱与时间);反之,若均初始化为-INF
则最终f[m][t]
的值表示一定填满[m][n]
的背包所获得的最大价值。这一部分可以参考动态规划算法的初始化和转移