算法训练 装箱问题(dp)
问题描述
有一个箱子容量为V(正整数,0<=V<=20000),同时有n个物品(0<n<=30),每个物品有一个体积(正整数)。
要求n个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。
有一个箱子容量为V(正整数,0<=V<=20000),同时有n个物品(0<n<=30),每个物品有一个体积(正整数)。
要求n个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。
输入格式
第一行为一个整数,表示箱子容量;
第二行为一个整数,表示有n个物品;
接下来n行,每行一个整数表示这n个物品的各自体积。
第二行为一个整数,表示有n个物品;
接下来n行,每行一个整数表示这n个物品的各自体积。
输出格式
一个整数,表示箱子剩余空间。
样例输入
24
6
8
3
12
7
9
7
样例输入
24
6
8
3
12
7
9
7
样例输出
0
思路: dp[i][j]表示前i个物品放入体积为j的箱子能得到的最大体积
转移方程 dp[i][j]=max(dp[i-1][j],dp[i-1][j-q[i]]+q[i]); 不放和放最后一个物品的区别
初始化:dp[0][j]=dp[i][0]=0
import java.util.Arrays; import java.util.Scanner; public class Main { /** * dp[i][j]表示前i个物品放入体积为j的箱子能得到的最大体积 * dp[i][j]=max(dp[i-1][j],dp[i-1][j-q[i]]+q[i]); 不放和放最后一个物品的区别 * dp[0][j]=dp[i][0]=0 */ static final int N=35; static final int M=20000+10; static int v; static int n; static int q[]=new int[N]; static int dp[][]=new int[N][M]; public static void main(String[] args) { Scanner sc=new Scanner(System.in); v=sc.nextInt(); n=sc.nextInt(); for(int i=1;i<=n;i++) q[i]=sc.nextInt(); for(int i=1;i<=n;i++){ for(int j=1;j<=v;j++){ if(j<q[i]) dp[i][j]=dp[i-1][j]; //当背包容积不够时 不装 else{ //装 dp[i][j]=Math.max(dp[i-1][j], dp[i-1][j-q[i]]+q[i]); } } } System.out.println(v-dp[n][v]); } }