剑指Offer(八)——动态规划

1、剪绳子

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

方案一:递归

我们先定义函数f(n)为把绳子剪成若干段之后的各段长度乘积的最大值。在剪第一刀的时候,我们会有n-1种可能的选择,也就是说剪出来的第一段绳子的长度可能为1,2,......n-1。

因此就有了递归公式 f(n) = max(f(i)*f(n-i)),其中0<i<n.

#递归写法
class Solution:
    def cutRope(self, number):
        # write code here
        if number < 2:
            return 0
        if number == 2:
            return 1
        if number == 3:
            return 2       
        return self.cutRopeCore(number)

    def cutRopeCore(self, number):
        if number < 4:
            return number
        max_ = 0
        for i in range(1, number/2+1):
            max_ = max(self.cutRopeCore(i) * self.cutRopeCore(number - i), max_)
        return max_

递归会产生大量不必要的重复计算,所以可以考虑采用动态规划的方法

方案二:贪婪

尽量把大于5的数分解成3的乘积,如果剩下的长度为4,则把4分解成2和2,因为3x1 < 2x2。

#贪婪算法
class Solution:
    def cutRope(self, number):
        # write code here
        if number < 2:
            return 0
        if number == 2:
            return 1
        if number == 3:
            return 2       
        #申请辅助空间
        timesOf3 = number / 3
        if (number - timesOf3*3) == 1:
            timesOf3 -= 1
        timesOf2 = (number - timesOf3*3) / 2
        return pow(3, timesOf3)*pow(2, timesOf2)

方案三:动态规划

从下而上的计算,即先求的f(2),f(3),再计算得到f(4),f(5),以此往后,直到f(n)

#递归写法
class Solution:
    def cutRope(self, number):
        # write code here
        if number < 2:
            return 0
        if number == 2:
            return 1
        if number == 3:
            return 2       
        products = [0]*(number+1)
        products[0] = 0
        products[1] = 1
        products[2] = 2
        products[3] = 3
        #动态规划
        for i in range(4,number+1):
            max_ = 0
            for j in range(1, i/2+1):
                max_ = max(products[j]*products[i-j], max_)
            products[i] = max_
        return products[number]

数学推导(证明)

https://blog.csdn.net/qq_33286988/article/details/100272288?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control&dist_request_id=1328603.47886.16151256525430079&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control

https://blog.csdn.net/qq_37340588/article/details/107723310?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-0&spm=1001.2101.3001.4242

猜你喜欢

转载自blog.csdn.net/caicai0001000/article/details/114498860