递推公式:
p
[
i
,
c
]
=
m
a
x
{
P
[
i
−
1
,
c
−
v
[
i
]
]
+
p
[
i
]
,
p
[
i
−
1
,
c
]
}
p[i,c]=max\{P[i -1, c-v[i]] + p[i], p[i-1,c] \}
p[i,c]=max{P[i−1,c−v[i]]+p[i],p[i−1,c]}
伪代码
上面三种方法的代码实现
packagecom.tiger.study;importjava.util.ArrayList;importjava.util.HashMap;publicclassBagProblem{publicstaticvoidmain(String[] args){int[][] priceAndV ={{24,10},{2,3},{9,4},{10,5},{9,4}};int c =13;int[][] mem =newint[priceAndV.length +1][c +1];boolean[][] records =newboolean[priceAndV.length +1][c +1];for(int i1 =0; i1 < mem.length; i1++){
mem[i1][0]=0;
records[i1][0]=false;}for(int i1 =0; i1 < mem[0].length; i1++){
mem[0][i1]=0;
records[0][i1]=false;}HashMap<String,Integer> map =newHashMap<>();// System.out.println(KnapsackSREnum(priceAndV, priceAndV.length - 1, c, mem, records));KnapsackDP(priceAndV, priceAndV.length, c, mem, records);System.out.println(mem[priceAndV.length][c]);ArrayList<Integer> commoditys =newArrayList<>();int nums = priceAndV.length;while(nums >=0&& c >=0){if(records[nums][c]){
commoditys.add(nums);
c -= priceAndV[nums -1][1];
nums--;}else{
nums--;}}System.out.println(commoditys);for(int i =0; i < mem.length; i++){for(int i1 =0; i1 < mem[i].length; i1++){System.out.printf(mem[i][i1]+" ");}System.out.println();}}// 暴力枚举// 输出最大的总价格privatestaticintKnapsackSREnum(int[][] arr,int i,int c){if(c <0)return-Integer.MAX_VALUE;if(0>= i)return0;int v = arr[i][1];int p = arr[i][0];int p1 =KnapsackSREnum(arr, i -1, c - v);int p2 =KnapsackSREnum(arr, i -1, c);int maxP =Math.max(p1 + p, p2);return maxP;}// 动态规划解1:带备忘录递归privatestaticintKnapsackSREnum(int[][] arr,int i ,int c,HashMap<String,Integer> map){if(c <0)return-Integer.MAX_VALUE;if(0>= i)return0;if(map.containsKey(i +","+ c))return map.get(i +","+ c);int p = arr[i][0];int v = arr[i][1];int p1 =KnapsackSREnum(arr, i -1, c - v, map);int p2 =KnapsackSREnum(arr, i -1, c, map);int pMax =Math.max(p1 + p, p2);
map.put(i +","+ c, pMax);return map.get(i +","+ c);}privatestaticintKnapsackSREnum(int[][] arr,int i,int c,int[][] memorandums){if(c <0)return-Integer.MAX_VALUE;if(i <=0)return0;int p = arr[i][0];int v = arr[i][1];int p1 =KnapsackSREnum(arr, i -1, c, memorandums);int p2=KnapsackSREnum(arr, i -1, c - v, memorandums)+ p;if(p1 > p2){
memorandums[i][c]= p1;}else{
memorandums[i][c]= p2;}return memorandums[i][c];}privatestaticintKnapsackSREnum(int[][] arr,int i,int c,int[][] memorandums,boolean[][] records){if(c <0)return-Integer.MAX_VALUE;if(i <=0)return0;int p = arr[i][0];int v = arr[i][1];int p1 =KnapsackSREnum(arr, i -1, c, memorandums, records);int p2=KnapsackSREnum(arr, i -1, c - v, memorandums, records)+ p;if(p1 < p2 && v <= c){
memorandums[i +1][c]= p2;
records[i +1][c]=true;}else{
memorandums[i +1][c]= p1;
records[i +1][c]=false;}return memorandums[i +1][c];}// 自底向上:递推计算privatestaticvoidKnapsackDP(int[][] arr,int i,int c,int[][] memorandums,boolean[][] records){for(int i1 =1; i1 <= i; i1++){for(int i2 =1; i2 <= c; i2++){int v = arr[i1 -1][1];int p_i = arr[i1 -1][0];if(i2 < v){
memorandums[i1][i2]=0;
records[i1][i2]=false;continue;}int p_1= memorandums[i1 -1][i2 - v]+ p_i;int p_2 = memorandums[i1 -1][i2];if(p_1 >= p_2 && v <= i2){
memorandums[i1][i2]= p_1;
records[i1][i2]=true;}else{
memorandums[i1][i2]= p_2;
records[i1][i2]=false;}}}}}