zoukankan      html  css  js  c++  java
  • 数据结构与算法 -- 动态规划算法

    1、0-1背包问题

    //0-1背包问题--动态规划算法
    public class DynamicPlan {
    
        public static void main(String[] args) {
            DynamicPlan dynamicplan = new DynamicPlan();
            int[] weight = {1, 2, 3, 4, 5};
            System.out.println("方法一     背包所装物品的重量为:" + dynamicplan.knapsack(weight, weight.length, 12));
            System.out.println("方法二     背包所装物品的重量为:" + dynamicplan.knapsack2(weight, weight.length, 12));
        }
    
        //方法一      weight:物品重量,n:物品个数,w:背包可承载重量
        public int knapsack(int[] weight, int n, int w) {
            boolean[][] states = new boolean[n][w+1];//默认值false
            states[0][0] = true;//第一行的数据要特殊处理,可以利用哨兵优化
            if(weight[0] <= w) {
                states[0][weight[0]] = true;
            }
            for(int i=1; i<n; i++) {//动态规划状态转移
                for(int j=0; j<=w; j++) {//不把第i个物品放入背包
                    if(states[i-1][j] == true) {
                        states[i][j] = states[i-1][j];
                    }
                }
                for(int j=0; j<=w-weight[i]; j++) {//把第i个物品放入背包
                    if(states[i-1][j] == true) {
                        states[i][j+weight[i]] = true;
                    }
                }
            }
            for(int i=w; i>=0; i--) {//输出结果
                if(states[n-1][i] == true) {
                    return i;
                }
            }
            return 0;
        }
        
        //方法二      weight:物品重量,n:物品个数,w:背包可承载重量
        public int knapsack2(int[] weight, int n, int w) {
            boolean[] states = new boolean[w+1];//默认值false
            states[0] = true;//第一行的数据要特殊处理,可以利用哨兵优化
            if(weight[0] <= w) {
                states[weight[0]] = true;
            }
            for(int i=1; i<n; i++) {//动态规划状态转移
                for(int j=w-weight[i]; j>=0; j--) {//把第i个物品放入背包
                    if(states[j] == true) {
                        states[j+weight[i]] = true;
                    }
                }
            }
            for(int i=w; i>=0; i--) {//输出结果
                if(states[i] == true) {
                    return i;
                }
            }
            return 0;
        }
    }

     2、0-1背包问题【升级版】

    //0-1背包问题【升级版】--动态规划算法
    public class DynamicPlan {
    
        public static void main(String[] args) {
            DynamicPlan dynamicplan = new DynamicPlan();
            int[] weight = {2, 2, 4, 6, 3};//物品的重量
            int[] value = {3, 4, 8, 9, 6};//物品的价值
            int n = 5;//物品个数
            int w = 9;//背包承受的最大重量
            System.out.println("背包所装物品的最大价值为:" + dynamicplan.knapsack3(weight, value, n, w));
        }
    
        //方法一      weight:物品重量,n:物品个数,w:背包可承载重量
        public int knapsack3(int[] weight, int[] value, int n, int w) {
            int[][] states = new int[n][w+1];
            for(int i=0; i<n; i++) {//初始化states
                for(int j=0; j<w+1; j++) {
                    states[i][j] = -1;
                }
            }
            states[0][0] = 0;
            if(weight[0] <= w) {
                states[0][weight[0]] = value[0];
            }
            for(int i=1; i<n; i++) {//动态规划状态转移
                for(int j=0; j<=w; j++) {//不把第i个物品放入背包
                    if(states[i-1][j] >= 0) {
                        states[i][j] = states[i-1][j];
                    }
                }
                for(int j=0; j<=w-weight[i]; j++) {//把第i个物品放入背包
                    if(states[i-1][j] >= 0) {
                        int v = states[i-1][j] + value[i];
                        if(v > states[i][j+weight[i]]) {
                            states[i][j+weight[i]] = v;
                        }
                    }
                }
            }
            //找出最大值
            int maxValue = -1;
            for(int j=0; j<=w; j++) {
                if(states[n-1][j] > maxValue) {
                    maxValue = states[n-1][j];
                }
            }
            return maxValue;
        }
    }

    3、"双十一"购物拼单问题

    /**
     * "双十一"购物拼单问题--动态规划算法
     * 
     * "双十一"购物节举办一个"满200元减50元"的促销活动,假设你女朋友的购物车中有
     * n(n>100)个想买的商品,她希望从里面选几个,在凑够满减条件的前提下,让选出来
     * 的商品价格和最大程度的接近满减条件(200元),这样就可以极大限度的"薅羊毛"
     */
    public class DynamicPlan {
    
        public static void main(String[] args) {
            DynamicPlan dynamicplan = new DynamicPlan();
            int[] items = {12, 25, 48, 6, 33, 120, 59, 88, 4, 71, 169, 23, 112};
            dynamicplan.double11advance(items, items.length, 200);
        }
        
        //items 商品价格,n 商品个数,w 表示满减条件,比如200
        public void double11advance(int[] items, int n, int w) {
            boolean[][] states = new boolean[n][3*w+1];//超过3倍就没有薅羊毛的价值了
            states[0][0] = true;//第一行的数据要特殊处理
            if(items[0] <= 3*w) {
                states[0][items[0]] = true;
            }
            for(int i=1; i<n; i++) {//动态规划
                for(int j=0; j<=3*w; j++) {//不购买第i个商品
                    if(states[i-1][j] == true) {
                        states[i][j] = states[i-1][j];
                    }
                }
                for(int j=0; j<=3*w-items[i]; j++) {//购买第i个商品
                    if(states[i-1][j] == true) {
                        states[i][j+items[i]] = true;
                    }
                }
            }
            
            int j;
            for(j=w; j<3*w+1; j++) {
                if(states[n-1][j] == true) {
                    break;//输出结果大于等于w的最小值
                }
            }
            if(j == 3*w+1) {
                return;//没有可行解
            }
            for(int i=n-1; i>=1; i--) {//i表示二维数组中的行,j表示列
                if(j-items[i] >= 0 && states[i-1][j-items[i]] == true) {
                    System.out.print(items[i] + " ");//购买这个商品
                    j = j - items[i];
                }//else 没有购买这个商品,j不变
            }
            if(j != 0) {
                System.out.print(items[0]);
            }
        }
    }
  • 相关阅读:
    暑假第三周
    暑假第二周
    bzoj3572:[Hnoi2014]世界树
    bzoj3998:[TJOI2015]弦论
    luoguP4242树上的毒瘤
    bzoj1339/1163:[Baltic2008]Mafia
    bzoj3507:[Cqoi2014]通配符匹配
    bzoj1449:[JSOI2009]球队收益/bzoj2895:球队预算
    bzoj2243:[SDOI2011]染色
    bzoj4516:[Sdoi2016]生成魔咒
  • 原文地址:https://www.cnblogs.com/jiangwangxiang/p/11072573.html
Copyright © 2011-2022 走看看