有 N件物品和一个容量是 V 的背包,背包能承受的最大重量是 M。
每件物品只能用一次。体积是 vi,重量是 mi,价值是 wi。
求解将哪些物品装入背包,可使物品总体积不超过背包容量,总重量不超过背包可承受的最大重量,且价值总和最大。
输出最大价值。
输入格式:
第一行三个整数,N,V,M,用空格隔开,分别表示物品件数、背包容积和背包可承受的最大重量。
接下来有 N行,每行三个整数 vi,mi,wi,用空格隔开,分别表示第 i 件物品的体积、重量和价值。
输出格式:
输出一个整数,表示最大价值。
数据范围:
0<N≤1000
0<V,M≤100
0<vi,mi≤100
0<wi≤1000
输入样例:
4 5 6
1 2 3
2 4 4
3 4 5
4 5 6
输出样例:
8
解题思路: 本题思路和以往大致一样,只不过多了一个物品质量。设立函数 f(i , j, k) 即表示在考虑前i件物品,背包体积为j,背包最大载重为k时,所装入的最大价值。但由于编程中没有三位数组 f [i] [j] [k]。所以可以借鉴之前滚动一维数组代替二维数组,即利用滚动二维数组代替三维数组。
对 f(i , j, k) 进行分析,当不选第i件物品时取 f(i - 1, j, k),选第i件物品时取f(i - 1, j - v, k - m) + w。
由于是01背包,所以优化后循环是从大到小。
综上,结论成立代码如下:
import java.util.*;
public class Main {
public static int N = 1010;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n0 = sc.nextInt();
int v0 = sc.nextInt();
int m0 = sc.nextInt();//输入物品数量,背包容积,背包承受质量。
int v[] = new int [N];
int m[] = new int [N];
int w[] = new int [N];//储存商品的体积,质量,价值
for(int i = 1; i <= n0; i ++) {
v[i] = sc.nextInt(); m[i] = sc.nextInt(); w[i] = sc.nextInt();
}
int f[][] = new int [110][110];//滚动二维数组
for(int i = 1; i <= n0; i ++)
for(int j = v0; j >= v[i]; j --)
for(int k = m0; k >= m[i]; k --) {
f[j][k] = Math.max(f[j][k],f[j - v[i]][k - m[i]] + w[i]);
}
System.out.print(f[v0][m0]);
}
}