1. 问题描述
2. 思路分析
二维动态规划的的状态转移方程为:
dp[i][j] = max(dp[i-1][j], dp[i-1][j-v[i]] + w[i])
(1) 果不装第 i件物品,问题就转化为“前 i−1 件物品放入容量为 j的背包中的最大价值”
(2) 装第i件物品,问题转化为“前 i−1 件物品放入剩下容量为 j−v[i] 的背包中的最大价值”
状态转移方程:定义f[i][j]:前i个物品,背包容量j下的最优解
1)当前背包容量不够(j < w[i]),为前i-1个物品最优解:f[i][j] = f[i-1][j]
2)当前背包容量够,判断选与不选第i个物品
选:f[i][j] = f[i-1][j-w[i]] + v[i]
不选:f[i][j] = f[i-1][j]
3、代码实现
import java.util.Scanner;
/**
* 1)当前背包容量不够(j < w[i]),为前i-1个物品最优解:f[i][j] = f[i-1][j]
* 2)当前背包容量够,判断选与不选第i个物品
* 选:f[i][j] = f[i-1][j-w[i]] + v[i]
* 不选:f[i][j] = f[i-1][j]
*/
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while(scanner.hasNext()){
//获取物品的数量N
int N = scanner.nextInt();
//获取背包的容积V
int V = scanner.nextInt();
//创建数组,第i个元素表示第i个物品的体积
int[] v = new int[N+1];
//创建数组,第i个元素表示第i个物品的价值
int[] w = new int[N+1];
//v[i]和w[i]分别表示第i件物品的体积和价值
for(int i=1;i<=N;i++){
v[i] = scanner.nextInt();
w[i] = scanner.nextInt();
}
/**
* 定义一个二维数组:dp[N+1][V+1]
* 这里之所以要N+1和V+1:
* 1、第0行表示只能选择第0个物品的时候,即没有物品的时候
* 2、第0列表示背包的体积为0的时候,即不能装任何东西的时候
*/
int[][] dp = new int[N+1][V+1];
/**
* dp[i][j]:在只能选择前i个物品且背包容量为j的情况下,背包中物品的最大价值
*
* 1、当前背包容量不够(j < w[i]),为前i-1个物品最优解:dp[i][j] = dp[i-1][j]
* 2、当前背包容量够,判断选与不选第i个物品
* 1、选:dp[i][j] = dp[i-1][j-w[i]] + v[i]
* 2、不选:dp[i][j] = dp[i-1][j]
*/
for(int i = 1; i <= N; i++){
for(int j = 1; j <= V; j++){
if(j >= v[i]){
//判断选与不选当前物品
dp[i][j] = Math.max(dp[i-1][j], dp[i-1][j-v[i]] + w[i]);
}else{
dp[i][j] = dp[i-1][j];
}
}
}
System.out.println(dp[N][V]);
}
}
}
优化为一维数组:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while(scanner.hasNext()){
//获取物品的数量N
int N = scanner.nextInt();
//获取背包的容积V
int V = scanner.nextInt();
//创建数组,第i个元素表示第i个物品的体积
int[] v = new int[N+1];
//创建数组,第i个元素表示第i个物品的价值
int[] w = new int[N+1];
//v[i]和w[i]分别表示第i件物品的体积和价值
for(int i=1;i<=N;i++){
v[i] = scanner.nextInt();
w[i] = scanner.nextInt();
}
int[] dp = new int[V+1];
for(int i = 1; i <= N; i++){
for(int j = V; j >= v[i]; j--){
dp[j] = Math.max(dp[j], dp[j-v[i]] + w[i]);
}
}
System.out.println(dp[V]);
}
}
}