背包DP
本文最后更新于:2024年2月12日 晚上
0-1背包
背包容量为$W$,物品数量为$n$,每个物品的重量为$w{i}$,价值为$v{i}$。
每个物品都只有一件,求背包能装下的最大价值?
状态定义
$dp[i][j]$:从前$i$个物品中选出总重量不超过$j$的最大价值。
状态转移方程
$dp[i][j]= \begin{cases}
dp[i - 1][j], \ j
\end{cases}$
最终答案为:$dp[n][W]$
int[][] dp = new int[n + 1][W + 1];
int[] w = new int[n];
int[] v = new int[n];
// dp
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= W; j++) {
// 背包容量小于当前物品重量
if (j < w[i - 1]) {
dp[i][j] = dp[i - 1][j];
}
// 背包容量可以装的下当前物品
else {
dp[i][j] = Math.max(dp[i - 1][j], dp[i -1][j - w[i - 1]] + v[i -1]);
}
}
}
// ans = dp[n][W];
空间优化
可以发现,计算当前行状态时,只与上一行的状态有关,所以可以用滚动数组来优化空间。
int[] dp = new int[W + 1];
int[] w = new int[n];
int[] v = new int[n];
// dp
for (int i = 1; i <= n; i++) {
int[] temp = new int[W + 1];
for (int j = 0; j <= W; j++) {
if (j < w[i - 1]) {
temp[j] = dp[j];
} else {
temp[j] = Math.max(dp[j], d[j - w[i - 1]] + v[i - 1]);
}
}
dp = temp;
}
// ans = dp[W]
本文作者: MerickBao
本文链接: https://merickbao.top/post/%E7%AE%97%E6%B3%95/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92/%E8%83%8C%E5%8C%85DP.html
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!