1、问题描述
有N件物品和一个容量为y的背包。第i件物品的价值是v[i],体积是w[i]。求解将哪些物品装入背包可使价值总和最大。
2、基本思路
假设物品编号从1到n,一件一件物品考虑是否加入背包。
假设dp[x][y]表示前x件物品,不超过重量y的时候的最大价值。枚举一下第x件物品的情况:
情况一:如果选择第x件物品,则前x-1件物品得到的重量不能超过y-w[x]。
情况二:如果不选第x件物品,则前x-1件物品得到的重量不能超过y。
所以,dp[x][y]可能等于d[x-1][y],也就是不取第x件物品的时候,价值和之前一样。
也可能是dp[x-1][y-w[x]]+v[x],也就是决定拿第x件物品的情况,当然会获得x物品的价值。
两种可能性中,应该选择价值最大的那个。
两种可能性中,应该选择价值最大的那个。dp[x][y]=max{dp[x-1][y],dp[x-1][y-w[x]]+v[x]}。
对于dp矩阵来说,行数是物品的数量n,列数是背包的重量y,都从0开始,中间的值是选择相应物品后所得到的总重量。
例如有3个物品,背包的容量为10,相应的dp矩阵如下所示:
动态规划代码实现如下:
public class Main32 {
public static int beiBao(int[] weight,int []value,int maxWeight){
int n = weight.length;
int[][] maxValue = new int[n+1][maxWeight+1];
for(int m=0;m<n+1;m++){
for(int h=0;h<maxWeight+1;h++){
maxValue[m][h] = 0;
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=maxWeight;j++){
maxValue[i][j] = maxValue[i-1][j];
if(weight[i-1]<=j){
if((maxValue[i-1][j-weight[i-1]]+value[i-1]) > maxValue[i-1][j]){
maxValue[i][j] = maxValue[i-1][j-weight[i-1]]+value[i-1];//二维数组的第一个商品是一维数组的第0个商品
}
}
}
}
return maxValue[n][maxWeight];
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int weight[] = {0,3,4,5};
int value[] = {0,4,5,6};
int maxWeight = 10;
int result = beiBao(weight,value,maxWeight);
System.out.println(result);
}
}