0-1背包问题描述如下:
有一个容量为V的背包,和一些物品。这些物品分别有两个属性,体积w和价值v,每种物品只有一个。要求用这个背包装下价值尽可能多的物品,求该最大价值,背包可以不被装满。因为最优解中,每个物品都有两种可能的情况,即在背包中或者不存在(背 包中有0个该物品或者 1个),所以我们把这个问题称为0-1背包问题。
用dp[i][j]表示前i个物品在总体积不超过j的情况下,放到背包里的最大价值。由此可以推出状态转移方程:
dp[0][j] = 0;
dp[i][j] = max{dp[i-1][j-v[i]] + w[i],dp[i-1][j]};
上面的式子应该很好理解,当第i物品的体积小于当前剩余的体积,则说明可以装入背包,那么dp[i][j] = dp[i-1][j-v[i]]+w[i]。反之就是不能转入背包,dp[i][j] = dp[i-1][j]。
#include <iostream> using namespace std; #define MAXSIZE 100 int w[MAXSIZE]; int v[MAXSIZE]; int maxv; int n; int dp[MAXSIZE][MAXSIZE]; int max(int a, int b) { if (a > b) return a; else return b; } int main() { cin >> n >> maxv; for (int i = 1; i <= n; i++) { cin >> w[i] >> v[i]; } for (int i = 0; i <= maxv; i++) dp[0][i] = 0; for (int i = 1; i <= n; i++) { //只有当j >= w[i],dp[i][j]才能进行选取最大值 for (int j = maxv; j >= w[i]; j--) { dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - w[i]] + v[i]); } //当j < w[i],说明第i个物品是不能转入背包的,故dp[i][j] = dp[i-1][j] for (int j = w[i] - 1; j >= 0; j--) dp[i][j] = dp[i - 1][j]; } cout << dp[n][maxv] << endl; return 0; }
时间: 2024-10-20 11:28:34