0-1背包以及完全背包
蓝桥杯对应题目
https://www.lanqiao.cn/problems/1174/learning/
https://www.lanqiao.cn/problems/1175/learning/
0-1背包题目描述
小明有一个容量为 VV 的背包。
这天他去商场购物,商场一共有 NN 件物品,第 ii 件物品的体积为 w_iw**i,价值为 v_iv**i。
小明想知道在购买的物品总体积不超过 VV 的情况下所能获得的最大价值为多少,请你帮他算算。
输入描述
输入第 11 行包含两个正整数 N,VN,V,表示商场物品的数量和小明的背包容量。
第 2\sim N+12∼N+1 行包含 22 个正整数 w,vw,v,表示物品的体积和价值。
1\leq N\leq10^21≤N≤102,1\leq V \leq 10^31≤V≤103,1 \leq w_i,v_i \leq10^31≤w**i,v**i≤103。
输出描述
输出一行整数表示小明所能获得的最大价值。
输入输出样例
示例 1
输入
5 20
1 6
2 5
3 8
5 15
3 3
输出
37
运行限制
- 最大运行时间:1s
- 最大运行内存: 128M
完全背包题目描述
小明有一个容量为 VV 的背包。
这天他去商场购物,商场一共有 NN 种物品,第 ii 种物品的体积为 w_iw**i,价值为 v_iv**i,每种物品都有无限多个。
小明想知道在购买的物品总体积不超过 VV 的情况下所能获得的最大价值为多少,请你帮他算算。
输入描述
输入第 11 行包含两个正整数 N,VN,V,表示商场物品的数量和小明的背包容量。
第 2\sim N+12∼N+1 行包含 22 个正整数 w,vw,v,表示物品的体积和价值。
1\leq N\leq10^31≤N≤103,1\leq V \leq 10^31≤V≤103,1 \leq w_i,v_i \leq10^31≤w**i,v**i≤103。
输出描述
输出一行整数表示小明所能获得的最大价值。
输入输出样例
示例 1
输入
5 20
1 6
2 5
3 8
5 15
3 3
输出
120
运行限制
- 最大运行时间:1s
- 最大运行内存: 256M
题解
使用一维数组
注意0-1背包要从大往小遍历 避免一个物品添加多次
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int N = scan.nextInt();
int V = scan.nextInt();
int[] weight = new int[N];
int[] value = new int[N];
for(int i = 0; i < N; i++){
weight[i] = scan.nextInt();
value[i] = scan.nextInt();
}
//一维滚动数组
int[] dp = new int[V+1];
for(int i = 0; i < N; i++){
for(int j = V; j >= weight[i]; j--){
dp[j] = Math.max(dp[j],dp[j-weight[i]] + value[i]);
}
}
System.out.println(dp[V]);
//在此输入您的代码...
scan.close();
}
}
而完全背包唯一不同就是内层循环的遍历方向是从小到大
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int N = scan.nextInt();
int V = scan.nextInt();
int[] weight = new int[N];
int[] value = new int[N];
for(int i = 0; i < N; i++){
weight[i] = scan.nextInt();
value[i] = scan.nextInt();
}
//一维滚动数组
int[] dp = new int[V+1];
for(int i = 0; i < N; i++){
for(int j = weight[i]; j <= V; j++){
dp[j] = Math.max(dp[j],dp[j-weight[i]] + value[i]);
}
}
System.out.println(dp[V]);
//在此输入您的代码...
scan.close();
}
}
另外注意,使用一维滚动数组必须外层遍历物品,内层遍历背包容量