100
#LS1082. 【入门】01背包

【入门】01背包

题目描述

NN 件物品和一个容量是 VV 的背包。每件物品只能使用一次

ii 件物品的体积是 viv_i,价值是 wiw_i

求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。 输出最大价值。

输入格式

第一行两个整数,NVN,V,用空格隔开,分别表示物品数量和背包容积。

接下来有 NN 行,每行两个整数 vi,wiv_i, w_i,用空格隔开,分别表示第 ii 件物品的体积和价值。

输出格式

输出一个整数,表示最大价值。

4 5
1 2
2 4
3 4
4 5
8

提示

【样例解释 1】

  • 可以选择 物品2 和 物品3
  • 总体积为:2 + 3 = 5
  • 总价值为:4 + 4 = 8

请同学们完善下面的代码(记忆化搜索)

int n, m;
int v[N], w[N];
int dp[N][M];  // dp[i][j]: 前 i 个物品, 体积不超过 j 的最大价值

// 前 i 个物品, 体积不超过 j 的最大价值
int solve(int i, int j) {
    // 终止条件
    if (dp[i][j] >= 0) return dp[i][j];
	
	// 分解为规模更小的问题
    dp[i][j] = 0;
	
	// 第一种情况:用了第 i 个物品
	
	// 第二种情况:没用第 i 个物品

	return dp[i][j];
}

for (int i = 1; i <= n; i++) for (int j = 0; j <= m; j++) dp[i][j] = -1;
请思考后再点击查看提示
  • 状态设计:dp(i,j)dp(i, j) 表示从前 ii 个物品中选出体积不超过 jj 的物品时的最大价值
  • 状态转移
$$\begin{equation} dp(i,j) = \left\{ \begin{array}{lr} dp(i-1,j), & 不使用第i个物品 \\ dp(i-1,j-v(i))+w(i), & 使用第i个物品 \end{array} \right. \end{equation}$$

数据规模与限制

  • 0<N1000,0<V30000 \lt N \le 1000, 0 \lt V \le 3000
  • 0<vi,wi10000\lt v_i, w_i \le 1000