/** * FileName: Main * Author: Jerry * Date: 2020/1/27 19:58 * Description: 多重背包 */ public class Main { /* *int []num 每种商品的最大售卖数 * V 背包最大容积 * N 商品种类数 * */ public static void multiplePack(int V,int N,int []weight,int []value,int []num) { int [][] dp =new int[N+1][V+1]; int temp; int [] t =new int[N+1]; //初始化动态规划数组 for(int i=1;i<=N;i++) { for(int j=1;j<=V;j++) { if(j>=weight[i]) { int max = Math.min(num[i],j/weight[i]); for(int k=0;k<=max;k++) { temp=Math.max(dp[i-1][j],dp[i-1][j-k*weight[i]]+k*value[i]); if(dp[i][j]<temp) t[i]=k; dp[i][j]=Math.max(dp[i][j],temp); } } else dp[i][j]=dp[i-1][j]; } } int maxValue = dp[N][V]; System.out.println("最大价值为"+maxValue); int j =V; String numStr = ""; for(int i=N;i>=1;i--) { if(dp[i][j]>dp[i-1][j]) { numStr=numStr+"商品种类"+i+"该商品共"+t[i]+"件 "; j=j-weight[i]; } if(j==0) break; } System.out.println(numStr); } public static void main(String[] args) { // TODO Auto-generated method stub int[] weight= {0,1,2,3}; int[] value= {0,6,13,20}; int[] num= {0,5,3,2}; int bagV=15; int N=3; multiplePack(bagV,N,weight,value,num); } }
|
2、多重背包:每类物品都有个数限制,第i类物品最多可以装num[i]次
由于每个物品多了数目限制,因此初始化和递推公式都需要更改一下。初始化时,只考虑一件物品a时,最大可提供量 max = min{num[1], j/weight[1]}。 计算考虑i件物品承重限制为y时最大价值f[i][j]时,递推公式考虑两种情况,要么第 i 件物品一件也不放,就是dp[i-1][j], 要么第 i 件物品放 k 件,其中 0<= k <=Math.min(num[i],j/weight[i]),
即f[i][j] = max{f[i-1][j], (f[i-1][j-kweight[i]]+kvalue[i])}。 需要判断第 i 件物品的个数是否超过限制数量 num[i]。