本文已参与「新人创作礼」活动,一起开启掘金创作之路。
往期
题目
有 种物品和一个容量是 的背包。
第 种物品最多有 件,每件体积是 ,价值是 。
求解将哪些物品装入背包,可使物品体积总和不超过背包容量,且价值总和最大。 输出最大价值。
输入格式
第一行两个整数,,,用空格隔开,分别表示物品种数和背包容积。
接下来有 行,每行三个整数 ,,,用空格隔开,分别表示第 种物品的体积、价值和数量。
输出格式
输出一个整数,表示最大价值。
数据范围
输入样例
4 5
1 2 3
2 4 1
3 4 3
4 5 2
输出样例
10
解题思路
多重背包问题:每个物品有件
完全背包问题:每个物品可以无限使用
因此,对于当前物品,仍然考虑取件、取件、...、取件,但除了考虑背包容量限制之外还需考虑物品数量限制,即: &&
- 状态定义
: 前个物品,在容量为的背包下,最大的价值
- 状态转移
&&
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt(); // 物品种数
int m = sc.nextInt(); // 背包容积
int[] v = new int[n+1];
int[] w = new int[n+1];
int[] s = new int[n+1];
int[][] dp = new int[n+1][m+1];
for (int i = 1; i <= n; i++) {
v[i] = sc.nextInt();
w[i] = sc.nextInt();
s[i] = sc.nextInt();
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
for (int k = 0; k <= s[i] && (k * v[i] <= j); k++) {
dp[i][j] = Math.max(dp[i][j], dp[i-1][j-k*v[i]]+k*w[i]); //k是从0开始更新的。因此当k=0时,实际上就是dp[i-1][j]
}
}
}
System.out.println(dp[n][m]);
}
}
时间复杂度: 空间复杂度: