动态规划算法轻松解决01背包,完全背包,多重背包问题


import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;

public class Dynamic {

    /**
     * 动态规划算法 :
     * 0-1 背包,多重背包 ,完全背包的求解
     * 假设有一个背包; 背包的最大承重量为 maxWeight  =  10, 有以下几种东西,其重量和价值分别如下
     * 名称    重量    价值
     * 牙刷     1       1
     * 牙膏     2       1
     * 剃须刀  3       2
     * 圣经     4       3
     * 手电筒  4       4
     * 睡袋     6       5
     * 帐篷    10      5
     *
     * 问 : 如果装入适当的东西,使得装入背包的东西总价值最大 ?
     *
     * 问题1 :  0-1背包,每种东西只能装入一种 ,不能重复
     * 问题2 :   无限背包, 每种东西装入的个数不限
     * 问题3  : 多重背包,第 i 中 东西最多可以装 i+1 个。
     * **/

    public static void main(String[] args) {
        int maxWeight = 10;
        int[][] info = new int[7][2];  // info[i][0]  表示第 i 件商品的重量  info[i][1] 表示第 i 种商品的价值
        info[0][0] = 1;
        info[0][1] = 1;

        info[1][0] = 2;
        info[1][1] = 3;

        info[2][0] = 3;
        info[2][1] = 2;

        info[3][0] = 4;
        info[3][1] = 3;

        info[4][0] = 4;
        info[4][1] = 4;

        info[5][0] = 6;
        info[5][1] = 0;

        info[6][0] = 10;
        info[6][1] = 0;

//        Dynamic1(info,maxWeight);
//        Dynamic2(info,maxWeight);
        Dynamic3(info,maxWeight);


    }

    /**  0-1  背包   */
    public static void Dynamic1(int[][] info ,int maxWeight){
        int row =  info.length +1;
        int col = maxWeight + 1;
        int[][] res = new int[row][col];
        for(int i=1;i<row;i++){
            for(int j=1;j<col;j++){
                if(info[i-1][0] > j ){
                    res[i][j] = res[i-1][j];
                }else{
                    res[i][j] =  Math.max(res[i-1][j]    ,     info[i-1][1] + res[i-1][  j-info[i-1][0]  ]);
                }
            }
        }
        System.out.println("背包可以装的最大价值是 : "+res[row-1][col-1]);
    }

    /**  无穷背包   */
    public static void Dynamic2(int[][] info ,int maxWeight){
        int row =  info.length +1;
        int col = maxWeight + 1;
        int[][] res = new int[row][col];
        for(int i=1;i<row;i++){
            for(int j=1;j<col;j++){
                if(info[i-1][0] > j ){
                    res[i][j] = res[i-1][j];
                }else{
                    res[i][j] =  Math.max(res[i-1][j]    ,     info[i-1][1] + res[i][  j-info[i-1][0]  ]);
                }
            }
        }
        System.out.println("背包可以装的最大价值是 : "+res[row-1][col-1]);
    }

    /**  多重背包   */
    public static void Dynamic3(int[][] info ,int maxWeight){
        int row =  info.length +1;
        int col = maxWeight + 1;
        int[][] res = new int[row][col];
        for(int i=1;i<row;i++){
            for(int j=1;j<col;j++){
                if(info[i-1][0] > j ){
                    res[i][j] = res[i-1][j];
                }else{
                    ArrayList<Integer> arr =  new ArrayList<>();
                    for(int count=0;count <= i;count++){
                        int m =  j - info[i-1][0] * count ;
                        if(m < 0 ) break;
                        arr.add( info[i-1][1] * count + res[i-1][ m ] );
                    }
                    Collections.sort(arr);
                    res[i][j] = arr.get(arr.size()-1);
                }
            }
        }
        System.out.println("背包可以装的最大价值是 : "+res[row-1][col-1]);
    }
    
}

posted @ 2020-08-20 16:58  同济小孙  阅读(365)  评论(0编辑  收藏  举报