背包问题初接触
来源:互联网 发布:ubuntu输入法不对 编辑:程序博客网 时间:2024/06/07 06:55
ZeroOnePack
有N件物品和一个容量为V的背包。第i件物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使价值总和最大。
ZeroOnePack.txt
3 10 #(物品个数,背包容量)6 6 #(体积,价值)6 71 2
import java.io.InputStream;import java.util.Scanner;/** * 有N件物品和一个容量为V的背包。第i件物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使价值总和最大。 */public class ZeroOnePack { public static void main(String[] args) throws Exception { getMaxValue(); } /** * 3 10 * 3 4 * 4 5 * 5 6 * * @return * @throws Exception */ public static int getMaxValue() throws Exception { int maxValue = 0; InputStream is = ZeroOnePack.class.getClassLoader().getResourceAsStream("algorithm/bag/bag01/ZeroOnePack.txt"); Scanner scanner = new Scanner(is); int N = scanner.nextInt();//物品个数 int V = scanner.nextInt();//背包容量 int[] c = new int[N + 1];//物品体积,默认初始化为0,为了方便理解角标从1开始 int[] w = new int[N + 1];//物品价值 int[] f = new int[V + 1];//存储结果 for (int k = 1; k <= 3; k++) { c[k] = scanner.nextInt(); w[k] = scanner.nextInt(); } /** * 理解: * f[i][v] = max {f[i][v],f[i-1][v-c[i]]+w[i]} * 优化: * f[v] = max{f[v],f[v-c[i]]+w[i]} */ showF(f); //n件物品 for (int i = 1; i <= N; i++) { // 第i件物品。比较放入后(占v份空间下的价值)与不放(原来i-1物品占v份空间)价值大小 for (int v = V; v >= c[i]; v--) { if (f[v - c[i]] + w[i] > f[v]) { f[v] = f[v - c[i]] + w[i]; } showF(f); } } //showF(f); return maxValue; } public static void showF(int[] f) { for (int k = 1; k < f.length; k++) { System.out.printf("%d\t", f[k]); } System.out.println(); }}
输出
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6 0 0 0 0 0 0 0 0 6 6 0 0 0 0 0 0 0 6 6 6 0 0 0 0 0 0 6 6 6 6 0 0 0 0 0 6 6 6 6 6 0 0 0 0 0 6 6 6 6 7 0 0 0 0 0 6 6 6 7 7 0 0 0 0 0 6 6 7 7 7 0 0 0 0 0 6 7 7 7 7 0 0 0 0 0 7 7 7 7 7 0 0 0 0 0 7 7 7 7 9 0 0 0 0 0 7 7 7 9 9 0 0 0 0 0 7 7 9 9 9 0 0 0 0 0 7 9 9 9 9 0 0 0 0 0 7 9 9 9 9 0 0 0 0 2 7 9 9 9 9 0 0 0 2 2 7 9 9 9 9 0 0 2 2 2 7 9 9 9 9 0 2 2 2 2 7 9 9 9 9 2 2 2 2 2 7 9 9 9 9
CompletePack
有N种物品和一个容量为V的背包,每种物品都有无限件可用。第i种物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
CompletePack.txt
3 10 #(物品个数,背包容量)6 6 #(体积,价值)6 71 2
import java.io.InputStream;import java.util.Scanner;/** * 完全背包 * 有N种物品和一个容量为V的背包,每种物品都有无限件可用。第i种物品的费用是c[i],价值是w[i]。 * 求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。 */public class CompletePack { public static void main(String[] args) throws Exception { getMaxValue(); } /** * 3 10 * 3 4 * 4 5 * 5 6 * * @return * @throws Exception */ public static int getMaxValue() throws Exception { int maxValue = 0; InputStream is = CompletePack.class.getClassLoader().getResourceAsStream("algorithm/bag/complete/CompletePack.txt"); Scanner scanner = new Scanner(is); int N = scanner.nextInt();//物品种类数目 int V = scanner.nextInt();//背包容量 int[] c = new int[N + 1];//物品体积,默认初始化为0,为了方便理解角标从1开始 int[] w = new int[N + 1];//物品价值 int[] f = new int[V + 1];//存储结果 for (int k = 1; k <= 3; k++) { c[k] = scanner.nextInt(); w[k] = scanner.nextInt(); } /** * 理解: * f[i][v] = max {f[i][v],f[i-1][v-c[i]]+w[i]} * 优化: * f[v] = max{f[v],f[v-c[i]]+w[i]} */ showF(f); //n件物品 for (int i = 1; i <= N; i++) { // 第i件物品。比较放入后(占v份空间下的价值)与不放(原来i-1物品占v份空间)价值大小// for (int v = V; v >= c[i]; v--) {//逆序是ZeroOnePack for (int v = c[i]; v <= V; v++) {//顺序是CompletePack if (f[v - c[i]] + w[i] > f[v]) { f[v] = f[v - c[i]] + w[i]; } showF(f); } } //showF(f); return maxValue; } public static void showF(int[] f) { for (int k = 1; k < f.length; k++) { System.out.printf("%d\t", f[k]); } System.out.println(); }}
中间运行结果
0 0 0 0 0 0 0 0 0 0 0 0 4 0 0 0 0 0 0 0 0 0 4 4 0 0 0 0 0 0 0 0 4 4 4 0 0 0 0 0 0 0 4 4 4 8 0 0 0 0 0 0 4 4 4 8 8 0 0 0 0 0 4 4 4 8 8 8 0 0 0 0 4 4 4 8 8 8 12 0 0 0 4 4 4 8 8 8 12 12 0 0 4 5 4 8 8 8 12 12 0 0 4 5 5 8 8 8 12 12 0 0 4 5 5 8 8 8 12 12 0 0 4 5 5 8 9 8 12 12 0 0 4 5 5 8 9 10 12 12 0 0 4 5 5 8 9 10 12 12 0 0 4 5 5 8 9 10 12 13 0 0 4 5 6 8 9 10 12 13 0 0 4 5 6 8 9 10 12 13 0 0 4 5 6 8 9 10 12 13 0 0 4 5 6 8 9 10 12 13 0 0 4 5 6 8 9 10 12 13 0 0 4 5 6 8 9 10 12 13
MultiplePack
有N种物品和一个容量为V的背包。第i种物品最多有n[i]件可用,每件费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
MultiplePack .txt
#第一组3 103 4 14 5 15 6 1#第二组3 103 4 104 5 105 6 10
import java.util.Scanner;import static java.lang.Math.max;import static java.lang.Math.min;/** * 多重背包 * <p> * 有N种物品和一个容量为V的背包。第i种物品最多有n[i]件可用,每件费用是c[i],价值是w[i]。 * 求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。 */public class MultiplePack { public static void main(String[] args) { getMaxValue(); } public static int getMaxValue() { int maxValue = 0; Scanner scanner = new Scanner(MultiplePack.class.getClassLoader().getResourceAsStream( "algorithm/bag/multiple/MultiplePack.txt")); int N = scanner.nextInt();//物品种类数目 int V = scanner.nextInt();//背包的容量 int[] c = new int[N + 1];//c[i]表示第i种物品的费用 int[] w = new int[N + 1];//w[i]表示第i种物品的价值 int[] n = new int[N + 1];//n[i]表示第i种物品的数量 int[] f = new int[V + 1];//f[]记录每次操作中间过程 for (int k = 1; k <= N; k++) { c[k] = scanner.nextInt(); w[k] = scanner.nextInt(); n[k] = scanner.nextInt(); } /** * 多重背包转成01背包 * */ for (int i = 1; i <= N; i++) { /** * 每种物品的个数,转换成了物品数为Σn[i]的01背包问题 */ for (int j = 1; j <= min(V / c[i], n[i]); j++) { for (int v = V; v >= c[i]; v--) { f[v] = max(f[v], f[v - c[i]] + w[i]); showF(f); } } } return maxValue; } public static void showF(int[] f) { for (int k = 1; k < f.length; k++) { System.out.printf("%d\t", f[k]); } System.out.println(); }}
两组中间结果
0 0 0 0 0 0 0 0 0 4 0 0 0 0 0 0 0 0 4 4 0 0 0 0 0 0 0 4 4 4 0 0 0 0 0 0 4 4 4 4 0 0 0 0 0 4 4 4 4 4 0 0 0 0 4 4 4 4 4 4 0 0 0 4 4 4 4 4 4 4 0 0 4 4 4 4 4 4 4 4 0 0 4 4 4 4 4 4 4 9 0 0 4 4 4 4 4 4 9 9 0 0 4 4 4 4 4 9 9 9 0 0 4 4 4 4 9 9 9 9 0 0 4 4 4 5 9 9 9 9 0 0 4 4 5 5 9 9 9 9 0 0 4 5 5 5 9 9 9 9 0 0 4 5 5 5 9 9 9 11 0 0 4 5 5 5 9 9 11 11 0 0 4 5 5 5 9 10 11 11 0 0 4 5 5 5 9 10 11 11 0 0 4 5 5 6 9 10 11 11 0 0 4 5 6 6 9 10 11 11 -------------------------------------------------------------0 0 0 0 0 0 0 0 0 4 0 0 0 0 0 0 0 0 4 4 0 0 0 0 0 0 0 4 4 4 0 0 0 0 0 0 4 4 4 4 0 0 0 0 0 4 4 4 4 4 0 0 0 0 4 4 4 4 4 4 0 0 0 4 4 4 4 4 4 4 0 0 4 4 4 4 4 4 4 4 0 0 4 4 4 4 4 4 4 8 0 0 4 4 4 4 4 4 8 8 0 0 4 4 4 4 4 8 8 8 0 0 4 4 4 4 8 8 8 8 0 0 4 4 4 8 8 8 8 8 0 0 4 4 4 8 8 8 8 8 0 0 4 4 4 8 8 8 8 8 0 0 4 4 4 8 8 8 8 8 0 0 4 4 4 8 8 8 8 12 0 0 4 4 4 8 8 8 12 12 0 0 4 4 4 8 8 8 12 12 0 0 4 4 4 8 8 8 12 12 0 0 4 4 4 8 8 8 12 12 0 0 4 4 4 8 8 8 12 12 0 0 4 4 4 8 8 8 12 12 0 0 4 4 4 8 8 8 12 12 0 0 4 4 4 8 8 8 12 13 0 0 4 4 4 8 8 8 12 13 0 0 4 4 4 8 8 9 12 13 0 0 4 4 4 8 9 9 12 13 0 0 4 4 4 8 9 9 12 13 0 0 4 4 5 8 9 9 12 13 0 0 4 5 5 8 9 9 12 13 0 0 4 5 5 8 9 9 12 13 0 0 4 5 5 8 9 9 12 13 0 0 4 5 5 8 9 10 12 13 0 0 4 5 5 8 9 10 12 13 0 0 4 5 5 8 9 10 12 13 0 0 4 5 5 8 9 10 12 13 0 0 4 5 5 8 9 10 12 13 0 0 4 5 5 8 9 10 12 13 0 0 4 5 5 8 9 10 12 13 0 0 4 5 5 8 9 10 12 13 0 0 4 5 5 8 9 10 12 13 0 0 4 5 5 8 9 10 12 13 0 0 4 5 6 8 9 10 12 13 0 0 4 5 6 8 9 10 12 13 0 0 4 5 6 8 9 10 12 13 0 0 4 5 6 8 9 10 12 13 0 0 4 5 6 8 9 10 12 13 0 0 4 5 6 8 9 10 12 13 0 0 4 5 6 8 9 10 12 13
阅读全文
0 0
- 背包问题初接触
- googlemap初接触问题
- 初接触WEB开发遇到的问题
- 初接触mysql出现的问题
- Java初解背包问题
- 背包01问题初理解
- 【无限背包】背包问题
- 背包问题---01背包
- 背包问题--部分背包
- 背包问题
- 背包问题
- 背包问题
- 背包问题
- 背包问题
- 背包问题
- 背包问题
- 背包问题
- 背包问题
- Redis快速入门
- C++基础
- Android开发学习之路--Android Studio项目目录结构简介
- java 23种设计模式 深入理解
- 文章标题
- 背包问题初接触
- SetWindowLong 用法总结
- 笔试面试高频题(C/C++)
- Ubuntu kindle_inject进程占用CPU过高的解决办法
- 设计模式之——Java版总览
- 什么是Intent
- VMware上centos网卡配置
- CRC16的代码段
- CodeForces 711A A. Bus to Udayland