具体来说,假设有 n n n个物品,其重量分别为 w 1 , w 2 , . . . , w n w_1, w_2, ..., w_n w1,w2,...,wn,对应的价值分别为 v 1 , v 2 , . . . , v n v_1, v_2, ..., v_n v1,v2,...,vn。背包的承载重量为 W W W。我们需要在这 n n n个物品中选择一些放入背包中,使得这些物品的总重量不超过 W W W,且总价值最大化。
数学公式可以表示为:
Maximize ∑ i = 1 n v i x i subject to ∑ i = 1 n w i x i ≤ W x i ∈ { 0 , 1 } , i = 1 , 2 , . . . , n \begin{align*} \text{Maximize} \quad & \sum_{i=1}^{n} v_ix_i \\ \text{subject to} \quad & \sum_{i=1}^{n} w_ix_i \leq W \\ & x_i \in \{0, 1\}, \quad i=1,2,...,n \end{align*} Maximizesubject toi=1∑nvixii=1∑nwixi≤Wxi∈{0,1},i=1,2,...,n
其中, x i x_i xi表示第 i i i个物品是否放入背包中。若 x i = 1 x_i=1 xi=1,表示放入;若 x i = 0 x_i=0 xi=0,表示不放入。
int lastStoneWeightII(vector<int>& stones)
{
int n = stones.size();
int sum = 0;
for (auto e : stones)sum += e;
vector<vector<int>> dp(n + 1, vector<int>(sum / 2 + 1));
for (int i = 1;i <= n;i++)
{
for (int j = 1;j <= sum / 2;j++)
{
dp[i][j] = dp[i - 1][j];
if (j >= stones[i - 1])dp[i][j] = max(dp[i - 1][j - stones[i - 1]] + stones[i - 1], dp[i - 1][j]);
}
}
int a = dp[n][sum / 2];
int b = sum - a;
return abs(a - b);
}
空间优化过的代码:二维---->一维
cpp复制代码
class Solution {
public:
int lastStoneWeightII(vector<int>& stones)
{
int n = stones.size();
int sum = 0;
for (auto e : stones)sum += e;
vector<int> dp(sum / 2 + 1);
for (int i = 1;i <= n;i++)
for (int j = sum / 2;j >= stones[i - 1];j--)
dp[j] = max(dp[j - stones[i - 1]] + stones[i - 1], dp[j]);
int a = dp[sum / 2];
int b = sum - a;
return abs(a - b);
}
};