题目
有 N 种物品和一个容量是 V 的背包。
第 i 种物品最多有 si 件,每件体积是 vi,价值是 wi。
求解将哪些物品装入背包,可使物品体积总和不超过背包容量,且价值总和最大。
输出最大价值。
输入格式:
第一行两个整数,N,V,用空格隔开,分别表示物品种数和背包容积。
接下来有 N 行,每行三个整数 vi,wi,si 用空格隔开,分别表示第 i 种物品的体积、价值和数量。
输出格式:
输出一个整数,表示最大价值。
数据范围:
0<N,V≤1000<N,V≤100
0<vi,wi,si≤100
代码
import java.util.Scanner;
public class _多重背包问题I {
public static void main(String[] args) {
Scanner scanner =new Scanner(System.in);
int N =scanner.nextInt();
int V=scanner.nextInt();
int[] dp=new int[V+1];
for (int i = 0; i < N; i++) {
int v=scanner.nextInt();
int w=scanner.nextInt();
int s=scanner.nextInt();
for(int j=V;j>=0;j--){
for(int k=1;k<=s&&k*v<=j;k++){
dp[j]=Math.max(dp[j],dp[j-k*v]+k*w);
}
}
}
System.out.println(dp[V]);
scanner.close();
}
}
详解
public static void main(String[] args) {
- 这是程序的主入口点。当你运行程序时,它将从这里开始执行。
2-3. Scanner scanner = new Scanner(System.in);
- 创建一个
Scanner
对象,用于从标准输入(通常是键盘)读取数据。
4-5. int N = scanner.nextInt();
- 读取一个整数
N
,它表示有多少种不同的物品。
6-7. int V = scanner.nextInt();
- 读取一个整数
V
,它表示背包的总容量。
int[] dp = new int[V + 1];
- 创建一个整数数组
dp
,其长度为V + 1
。这个数组将用于存储对于每个可能的背包容量(从0到V),能够获得的最大价值。
- 创建一个整数数组
11-17. for (int i = 0; i < N; i++) {
- 开始一个循环,遍历每种物品。
12-13. int v = scanner.nextInt();
- 读取当前物品的重量。
14-15. int w = scanner.nextInt();
- 读取当前物品的价值。
int s = scanner.nextInt();
- 读取当前物品的数量限制。
18-25. for (int j = V; j >= 0; j--) {
- 开始一个内循环,从背包的最大容量
V
遍历到0。
19-22. for (int k = 1; k <= s && k * v <= j; k++) {
- 这是多重背包问题的核心。这个循环允许你选择0到
s
个当前物品,但不超过背包的当前容量j
。
dp[j] = Math.max(dp[j], dp[j - k * v] + k * w);
- 更新
dp
数组。这一行代码的意思是,对于当前的背包容量j
,比较两个选项:不放入任何新的当前物品(保持dp[j]
不变)和放入k
个当前物品(dp[j - k * v] + k * w
)。选择两者中的较大值作为新的dp[j]
。
}
- 内循环结束。
}
- 外循环结束。
System.out.println(dp[V]);
- 输出
dp[V]
,即当背包容量为V
时能够获得的最大价值。
scanner.close();
- 关闭
scanner
对象,释放与其相关的资源。
}
- 主函数结束。