动态规划

Posted 從前以後

tags:

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

备注:给小组人员讲解算法临时准备的稿子,记录自己的点点滴滴。
定义:动态规划程序设计是对解最优化问题的一种途径、一种方法,而不是一种特殊算法。
动态规划算法通常用于求解具有某种最优性质的问题。在这类问题中,可能会有许多可行解。每一个解都对应于一个值,我们希望找到具有最优值的解。动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。若用分治法来解这类问题,则分解得到的子问题数目太多,有些子问题被重复计算了很多次。如果我们能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,这样就可以避免大量的重复计算,节省时间。

递归回顾:给定一个8*8的方格子,如下图所示,求A点到B点的最短路径有多少条?用算法实现。

分析:从A到B要求路径最短,则每一步只有两种走法,既向右走和向上走,中途一旦出现向左走和向右走,此时的路径就不是最短路径。于是就可以用坐标x和y分别记录出向右走和向上走情况。用函数F(m,n,x,y)表示路径的数量。
如果x=8或者y=8那么只有一种走法情况 F(m,n,x,y)=1;
如果x<8或者y<8那么F(m,n,x,y)= F(m,n,x+1,y)+ F(m,n,x,y+1);

public int getrsult(int m, int n, int x, int y) 
        if(x==m||y==n)
        
            return 1;
        
        if(x<m||y<n)
        
            return getrsult(m, n, x+1, y)+getrsult(m, n, x, y+1);
               
        return 0;
    

动态规划:背包问题

分析:对于7个人物品,每一个物品都可以选择放或者不放进去,因此就有两种结果。取F(I,weightleft)表示最大值,其中I为当前物品标号,weightleft为当前背包剩下的容量,CurrentObject表示当前物品
1, 当CurrentObjectWeight>M,放不进去,F(I,weightleft)= F(I+1,weightleft)
2,当CurrentObjectWeight《M,能放进去,但可以选择放或者不放。
F(I,weightleft)=max(F(I+1,weightleft)+F(I,weightleft-currentObjectWeight)+currentObjectValue;);

这里写代码片

介绍动态规划之前一定要现讲递归,动态规划其实就是在递归之上延生出来的,递归的算法本质上是数形结构的深度优先遍历,按照深度优先的原则,仅仅一个return语句就能把所有的路线全部走一遍。每走到头加1,因此得到结果。动态规划就是在深度遍历的时候加一个限制条件,比如上面背包问题,本质为递归,但是在深度遍历到头的时候,加一个比较相邻两个深度遍历得到的值,谁大,记录下谁。然后和相邻的树形节点比较,再取大值,一直取到最上层的树形节点,拿到背包的最优解。
上图的最短路径问题,如果每条路径上面加一个需要消耗的体力v,然后怎么走既是最短,又消耗体力最小,求消耗体力最小值,这样也就是在每次遍历的时候加一个比较条件就行了,然后记录下最小值,也就变成动态规划了。

背包代码:

public class DP 
    private BEAN bean[] =  new BEAN(35, 10), new BEAN(30, 40),
            new BEAN(6, 30), new BEAN(50, 50), new BEAN(40, 35),
            new BEAN(10, 40), new BEAN(25, 30) ;

    private int maxWeight;
    private int record[][];

    public DP(int maxWeight) 
        this.maxWeight = maxWeight;
        int m = bean.length + 1;
        int n = maxWeight + 1;
        record = new int[m][n];
        for (int i = 0; i < m; i++) 
            for (int j = 0; j < n; j++) 
                record[i][j] = -1;
            
        
    

    public int getResult(int i, int maxWeight) 
        int result;
        if (record[i][maxWeight] != -1) 
            result = record[i][maxWeight];
        
        if (i >= bean.length) 
            return 0;
        
        if (bean[i].getWeight() > maxWeight) 
            result = getResult(i + 1, maxWeight);
         else 
            result = Math.max(
                    getResult(i + 1, maxWeight),
                    getResult(i + 1, maxWeight - bean[i].getWeight())
                            + bean[i].getValue());
        

        record[i][maxWeight] = result;
        return result;
    

    public static void main(String[] s) 
        DP test = new DP(150);
        int result = test.getResult(0, 150);
        System.out.println(result);
    


public class BEAN 
    private int weight;
    private int value;

    public int getWeight() 
        return weight;
    

    public void setWeight(int weight) 
        this.weight = weight;
    

    public int getValue() 
        return value;
    

    public void setValue(int value) 
        this.value = value;
    

    public BEAN(int weight, int value) 
        this.weight = weight;
        this.value = value;
    



以上是关于动态规划的主要内容,如果未能解决你的问题,请参考以下文章

动态规划中的0-1背包问题怎么去理解?要求给出具体实例和详细步骤。。。

01背包问题(动态规划)

背包型动态规划

动态规划-01背包问题

动态规划 之背包问题(九讲)

0-1背包问题的动态规划实现