• 【LeetCode】面试题14-1. 剪绳子


    题目:

    思路:

    1、如果m是确定值,则这m段越平均它们的乘积越大(数学直觉)。所以遍历所有的M(最小2段,最大n段),计算当前m下的最大值,然后对比得到所有M下的最大值。
    2、不需要遍历所有的M,根据如下两条数学推论直接计算最大值

    • 将绳子以相等的长度等分为多段,得到的乘积最大。
    • 尽可能将绳子以长度3等分为多段时,乘积最大。
      • 当n<=3时,按照规则不切分。但题目要求必须切分(m>1),所以返回n-1
      • 当n>3时,求n除以3的整数部分a和余数b(n=3a+b),则
        • b=0,直接返回3^a

        • b=1,乘以1和没乘一样,所以将一个3拿出来和1一起分成两个2,返回4x3^(a-1)

        • b=2,返回2x3^a

    3、动态规划,对长度为n的绳子进行切割,可以划分成子问题(最优子结构、无后向性、重叠子问题)。递归函数为F(n)=max(i x (n-i), i x F(n-i)), i=1, 2, ..., n-2

    代码:

    Python

    import math
    class Solution(object):
        def cuttingRope(self, n):
            """
            :type n: int
            :rtype: int
            """
            # # 暴力搜索M切分段数,对每次切分尽量平分
            # res = 0
            # for i in range(2, n+1):
            #     a = n // i
            #     b = n % i
            #     tmp = math.pow(a, i - b) * math.pow(a + 1, b)
            #     if tmp > res:
            #         res = int(tmp)
            # return res
            
            # # 尽量平分,使得每段长度为3
            # if n <= 3:
            #     return n - 1
            # a = n // 3
            # b = n % 3
            # if b == 0:
            #     return int(math.pow(3, a))
            # if b == 1:
            #     return 4 * int(math.pow(3, a - 1))
            # if b == 2:
            #     return 2 * int(math.pow(3, a))
    
            # 动态规划
            dp = [0 for _ in range(n + 1)]
            dp[1] = 1
            dp[2] = 1
            for i in range(3, n + 1):  # 当前绳子长度为i
                for j in range(1, i):  # 第一刀切分长度
                    dp[i] = max(dp[i], j * (i - j), j * dp[i - j])
            return dp[n]
    

    相关问题

  • 相关阅读:
    手动创建DataSet数据集
    Ado.Net 参数化操作
    序列化和反序列化
    封装多个集合在一个类中
    窗体之间的传递
    C程序设计语言练习题1-12
    C程序设计语言练习题1-11
    C程序设计语言练习题1-10
    C程序设计语言练习题1-9
    C程序设计语言练习题1-8
  • 原文地址:https://www.cnblogs.com/cling-cling/p/12960921.html
Copyright © 2020-2023  润新知