数据结构与算法 -- 动态规划算法

Posted jiangwangxiang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构与算法 -- 动态规划算法相关的知识,希望对你有一定的参考价值。

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]);
        
    

 

以上是关于数据结构与算法 -- 动态规划算法的主要内容,如果未能解决你的问题,请参考以下文章

数据结构与算法 -- 动态规划算法

《数据结构与算法之美》28——动态规划理论

数据结构与算法题解|动态规划|——矩阵型动态规划

数据结构与算法学习——动态规划-1

算法设计与分析-动态规划

数据结构与算法简记--动态规划