问题描述
有一个箱子容量为V(正整数,0<=V<=20000),同时有n个物品(0<n<=30),每个物品有一个体积(正整数)。 要求n个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。
输入格式
第一行为一个整数,表示箱子容量; 第二行为一个整数,表示有n个物品; 接下来n行,每行一个整数表示这n个物品的各自体积。
输出格式
一个整数,表示箱子剩余空间。
样例输入
24 6 8 3 12 7 9 7
样例输出
0
这是一个背包问题,用动态规划来解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| import java.util.Scanner;
public class Main {
private static int[][] dpOne; private static int[] dpTwo;
public static void main(String[] args) { Scanner in = new Scanner(System.in); int V = in.nextInt(); int n = in.nextInt(); dpOne = new int[n + 1][V + 1]; int[] v = new int[n + 1]; for (int i = 1; i <= n; i++) { v[i] = in.nextInt(); } in.close(); MethodOne(n, v, V); System.out.println(V - dpOne[n][V]); dpTwo = new int[V + 1]; MethodTwo(n, v, V); System.out.println(V - dpTwo[V]); }
private static void MethodOne(int n, int[] v, int V) { for (int i = 1; i <= n; i++) { for (int j = 1; j <= V; j++) { if (j >= v[i]) { dpOne[i][j] = Integer.max(dpOne[i - 1][j], dpOne[i - 1][j - v[i]] + v[i]); } else { dpOne[i][j] = dpOne[i - 1][j]; } } } }
private static void MethodTwo(int n, int[] v, int V) { for (int i = 1; i <= n; i++) { for (int j = V; j > 0; j--) { if (j >= v[i]) { dpTwo[j] = Integer.max(dpTwo[j], dpTwo[j - v[i]] + v[i]); } } } } }
|