0-1背包问题
动态规划解法
0-1背包问题描述:
给定一个可装质量为target的背包,给定n个重量为weights[i]的物品(i可取0,n-1),这n个物品对应的价值为values[i](i可取0,n-1),问怎样装可以使背包中的物品价值最大。
- 动态规划解法:
- 首先需要考虑动态规划的五个步骤:
- (1)确定dp数组,dp[i][j]表示容量为j的背包,可选物品为0-i,可装的最大价值
- (2)初始化dp[][]数组,dp[i][0]均为0,dp[0][j]根据背包的容量大小,当背包容量小于第一个物品的重量时,dp[0][j]为0;当背包容量大于等于第一个物品的重量时,dp[0][j]为value[0]。
- (3)确定递推公式:当可选物品为0-i、背包容量为j时,即dp[i][j],从上一个状态可以推出,分为两种情况: 1、第i个物品的质量大于背包容量,那么第i个物品不能装入背包中;
2、第i个物品的质量小于背包容量,那么第i个物品可以装入背包中,那么又分为两种情况:
第i个物品装入背包:dp[i][j] = dp[i-1][j];
第i个物品不装入背包:dp[i][j] = dp[i-1][j - weights[i]] + values[i]; - (4)确定遍历顺序:先遍历物品,再遍历背包容量。这样的思路比较容易理解。
- (5)手动模拟dp[][]数组。
代码实现
public class bagProblem {
public static void main(String[] args) {
int weights[] = {1,3,4};
int values[] = {15,20,30};
int target = 4;
bagSolution(weights,values,target);
}
public static void bagSolution(int weights[],int values[],int target){
// 定义dp数组
int[][] dp = new int[weights.length][target+1];
// 初始化dp数组
for (int j = weights[0]; j <= target ; j++) {
dp[0][j] = values[0];
}
for (int i = 1; i < weights.length; i++) {
for (int j = 0; j <= target ; j++) {
if (j < weights[i]){
dp[i][j] = dp[i-1][j];
}else {
dp[i][j] = Math.max(dp[i-1][j],dp[i-1][j-weights[i]] + values[i]);
}
}
}
for (int i = 0; i < weights.length; i++) {
for (int j = 0; j <= target; j++) {
System.out.print(dp[i][j] + "\t");
}
System.out.println("\n");
}
}
}