[AcWing] 1024. 装箱问题(C++实现)01背包问题
1. 题目
2. 读题(需要重点注意的东西)
读题:
装箱需要体积
===》 体积
要求装箱体积最大
,每一个箱子有自身的体积
===》 价值
且每一个箱子只有选或不选两种情况
即:
体积 ===》 体积
体积===》 价值
思路:
将空间优化为二维:滚动数组
优化方式与[AcWing] 2. 01背包问题(C++实现)0-1背包问题模板题相同,在此不再赘述。
3. 解法
优化前
---------------------------------------------------解法---------------------------------------------------
import java.io.IOException;
import java.util.Scanner;
public class Main {
public static int N = 1010,M = 20010;
public static int[] v = new int[N]; // 体积
public static int[] w = new int[N]; // 价值
public static int[][] f = new int[N][M];
public static void main(String[] args) throws IOException {
Scanner sc = new Scanner(System.in);
int m = sc.nextInt(); // 总体积
int n = sc.nextInt(); // 总数量
for(int i = 1;i <= n;i++) v[i] = w[i] = sc.nextInt();
for(int i = 1;i <= n;i++){
for(int j = 0;j <= m;j++){
f[i][j] = f[i-1][j];
if(j >= v[i]) f[i][j] = Math.max(f[i][j],f[i-1][j-v[i]]+w[i]);
}
}
System.out.println(m - f[n][m]);
}
}
优化后
---------------------------------------------------解法---------------------------------------------------
import java.io.IOException;
import java.util.Scanner;
public class Main {
public static int N = 40, M = 20010;
public static int[] v = new int[N]; // 体积、价值
public static int[] f = new int[M];
public static void main(String[] args) throws IOException {
Scanner sc = new Scanner(System.in);
int m = sc.nextInt(); // 总体积
int n = sc.nextInt(); // 总数量
for(int i = 1;i <= n;i++) v[i] = sc.nextInt();
for(int i = 1;i <= n;i++)
for(int j = m;j >= v[i];j--)
f[j] = Math.max(f[j],f[j-v[i]]+v[i]);
System.out.println(m - f[m]);
}
}
可能存在的问题
4. 可能有帮助的前置习题
5. 所用到的数据结构与算法思想
- 动态规划
- 01背包问题
6. 总结
01背包模型,可以发展为不同的01背包题目
01背包模型的特征:
1. 可以将一个属性看成 价值;
2. 可以将一个属性看作 背包体积;
3. 每种物品只有选或不选两种情况,不能重复选。