背包问题板子总结(小于等于,等于,大于)
dp[i]:表示当体积≤i
的所有情况集合下的最大价值[如 AcWing2. 01背包问题等]
// dp[0] = 0; // 这种情况就是最基本的背包问题,无需特意初始化,只需要初值都是0就可以
......
for (int j = m; j >= v; j--) // 计算时严格保证任意状态下背包体积 >= 0
{
dp[j] = max(dp[j], dp[j - v] + w);
}
......
cout << dp[m] << endl; // 最大值就是简单的dp[m]
dp[i]:表示当体积==i
的所有情况集合下的最大价值[如AcWing12. 背包问题求具体方案等]
memset(dp, -0x3f, sizeof dp); // 初始化为∞(如果题目求max,就用+∞,求min,就用-∞)
dp[0] = 0; // 对dp[0]作为起始点单独初始化,求最大价值就初始化为0,求方案数就初始化为1
......
for (int j = m; j >= v; j--) // 计算时严格保证任意状态下背包体积 >= 0
{
dp[j] = max(dp[j], dp[j - v] + w);
}
......
int res = 0; // 注意这里是体积恰好为i的情况,所以最大值就不只是简单的dp[m]
for (int i = 0; i <= m; i++) res = max(res, dp[i]); // 需要一层循环求结果
cout << res << endl;
dp[i]:表示当体积≥i
的所有情况集合下的最小价值[如AcWing1020. 潜水员等]
memset(dp, 0x3f, sizeof dp); // 初始化为∞(如果题目求max,就用+∞,求min,就用-∞)
dp[0] = 0; // 对dp[0]作为起始点单独初始化,求最大价值就初始化为0,求方案数就初始化为1
......
for (int j = m; j >= 0; j--) // 计算时任意状态下背包的体积允许 < 0
{
dp[j][k] = min(dp[j][k], dp[max(0, j-v1)][max(0, k-v2)]+w);
}
......
cout << dp[m][n] << endl; // 最大值需要自己判断,可能还是dp[m][n]