动态规划

一、什么是动态规划

  不懂动态规划的程序猿,不是好攻城狮。
  在面试算法题时,当你看到以下四个特点时,脑海中就应该想到【动态规划】这四个词了。
【1】求一个问题的最优解(最大值或者最小值);
【2】该问题可以分解成类似的若干个子问题,即整个问题的最优解是依赖于各个子问题的最优解;
【3】分解后的子问题还有相互重叠的更小的子问题,换句话说在算法计算中我们会重复计算某些个子问题的值,因此,为了提高效率,我们需要合理利用(保存)已经计算过的值,不能做重复的操作;
【4】分析问题时,从整体到局部亦或说从上至下分析,解题时从下往上求解问题,这样可以利用已经计算过的值去解决更大一点问题的值。

二、应用实例

题目大意:

  给你一根长度为n的绳子,请把绳子剪成m段 (m和n都是整数,n>1并且m>1)每段绳子的长度记为k[0],k[1],…,k[m].请问k[0]k[1]…*k[m]可能的最大乘积是多少?例如,当绳子的长度为8时,我们把它剪成长度分别为2,3,3的三段,此时得到的最大乘积是18.

代码实现(java):

/**
 * @author lm
 * @create 2018-03-27 14:39
 * @desc dd
 **/
public class CuttingRope {

    public int maxAfterCutting(int length) {

        if (length < 2) return 0;
        if (length == 2) return  1;
        if (length == 3) return  2;

        /*
        声明整形数组,用于保存中间结果;
        子问题的最优解存储在数组中,数组中的第i个元素表示把长度为i的绳子剪成若干段后各段长度乘积的最大值。
         */
        int resultArr[] = new int[length + 1];
        resultArr[0] = 0;
        resultArr[1] = 1;
        resultArr[2] = 2;
        resultArr[3] = 3;

        int max = 0;
        //求每个i的最大值
        for (int i = 4; i <= length; i++) {
            max = 0;
            for (int j = 1; j <= i/2; j++) {
                int tempResult = resultArr[j] * resultArr[i - j];
                if (tempResult > max) {
                    max = tempResult;
                }
                resultArr[i] = max;
            }
        }
        max = resultArr[length];
        return max;
    }

}
//测试用例
public class CuttingRopeTest {
    CuttingRope cuttingRope = new CuttingRope();
    @Test
    public void maxAfterCutting() throws Exception {
        assertEquals(4, cuttingRope.maxAfterCutting(4));
        assertEquals(18, cuttingRope.maxAfterCutting(8));
        assertEquals(2, cuttingRope.maxAfterCutting(3));
    }

}

总结

  本题是一道典型的动态规划算法题,为了避免递归产生的重复计算,采用了从下而上的计算顺序实现。

你可能感兴趣的:(动态规划)