题号:NC16693
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
有一个箱子容量为V(正整数,0 ≤ V ≤ 20000),同时有n个物品(0<n ≤ 30),每个物品有一个体积(正整数)。
要求n个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。
输入描述:
1个整数,表示箱子容量 1个整数,表示有n个物品 接下来n行,分别表示这n个物品的各自体积
输出描述:
1个整数,表示箱子剩余空间。
示例1
输入
24 6 8 3 12 7 9 7
输出
0
java代码实现:
import java.util.Scanner;
public class Main {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int V = sc.nextInt();
int n = sc.nextInt();
int [] res = new int[n+1]; //存储所有的物品
int [][] dp = new int[n+1][V+1]; //dp[i][j]代表在背包容量为j的情况下,装i个物品的最大价值
for(int i = 1; i <= n; i++ ){
res[i] = sc.nextInt();
}
for(int i = 1; i <= n; i++){
for(int j = 1; j <= V; j++){
//此处是dp[][]的重要之处,就是写状态转移方程,根据上面所述dp[i][j]代表的是背包容量为j的情况下,装i个物品的最大价值
//也就是对于第i个物品,我们可以选择装或者不装。如果我们要装第i个物品的话,我们首先要保证当前的背包容量足够装下第i个物品,
//那么此时的最佳价值应该是dp[i-1][j-res[i]]+res[i]
//如果不装,那么就等于dp[i-1][j]
//取两者的最大值,就是dp[i][j],最后dp[n][v]就是最大价值
if(j >= res[i]){
dp[i][j] = Math.max(dp[i-1][j], dp[i-1][j-res[i]] + res[i]);
}else{
dp[i][j] = dp[i-1][j];
}
}
}
System.out.println(V - dp[n][V]);
sc.close();
}
}