剑指 Offer 14- I. 剪绳子 python 8ms 12.9mb

题目

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

示例 1:

输入: 2
输出: 1
解释: 2 = 1 + 1, 1 × 1 = 1
示例 2:

输入: 10
输出: 36
解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36
提示:

2 <= n <= 58

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/jian-sheng-zi-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路

题目分析

1.绳子长度n,切成m段
2.求每短长度的乘积最大

思路

1.我们可以用深度搜索解决这个问题,
2.题目条件非常简单,有没有其它特征呢?
3.假设分成了M段,最后的乘积可以表示为K[0]K[1]…K[M-1]
4.根据数论,大于1的数都可以分解成2和3的和,这样我们是不是可以把表达式分解
然后转换成其他形式的问题?
5.表达式转换(2a1+3b1)(2a2+3b2)…((2am+3bm))=2^a * 3^b
6.问题就转换成了 几个2乘几个3的问题了
7.那如何分配2和3的个数呢?通过假设,看能否找到规律
n = 2 11
n = 3 12
n = 4 13 22
n = 5 14 23
n = 6 12 24 33
再往后就是重复的了,根据观察除了n=4,时13大于22,其他时候都是3越多越乘积越大
那如何证明这点是否正确呢?
(2a1+3b1)(2a2+3b2) = 4a1a2 + 6a1b2 + 6a2b1 + 9b1b2
1.系数最大的项最大的时候 方程结果最大,9 b1b2这一项系数最大为9
所以b1,b2 >0时 b1 b2越大 也就是3越多越好
2.b1和b2有一个为0时 式子变为 4a1a2+6a1b2 或者 4a1a2+ 6a2b1
系数最大的项是6a1b2和6a2b1,这个时候a*b越大越好,a代表2的个数,b代表3的个数, 所以肯定时2越多越好,因为2a+3b=n
3.b1和b2都为0时 4a1a2, 全为2
所以当绳子分开之后,两边都不小于3的时候 3越多乘积越大
当分开后出现小于3的情况,则2越多乘积越大

代码

class Solution(object):
    def cuttingRope(self, n):
        """
        :type n: int
        :rtype: int
        """
        if n == 2:
            return 1
        if n == 3:
            return 2

        res = 1
        while n > 4:
            n = n - 3
            res = res * 3
        res = res * n
        return res

作者:liye-5u
链接:https://leetcode-cn.com/problems/jian-sheng-zi-lcof/solution/jian-zhi-offer-14-i-jian-sheng-zi-python-xshs/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值