码迷,mamicode.com
首页 > 其他好文 > 详细

343. Integer Break

时间:2018-10-09 21:44:09      阅读:111      评论:0      收藏:0      [点我收藏+]

标签:tput   inline   因子   isp   def   turn   end   object   input   

问题

将一个正整数分成至少两个正整数的和,使得最大化这些整数的乘积,给出最大乘积。

Input: 10
Output: 36
Explanation: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36

思路

什么时候pq > p + q,只要p和q都大于1就满足。在正整数里,两个为2时pq==p+q,所以只要一个至少为2,另一个至少为3即可,也就是p+q至少为5,那么只要一个数大于等于5,就可以把这个数分解成p+q,使得pq > p + q,如果p或者q里面还有大于等于5的数,就将p或q继续分解,不断往下分解,直到因子小于5。

因为要分解到小于5,所以最后的因子一定是2或者3(或者4),因为分成4和分成2是一样的(两个2和1个4的乘积相同),所以我们考虑3和2要怎么分配。

考虑一个数有m个3和n个2相加,即\(x = 3m + 2n\),那么积等于m个3和n个2相乘,定义一个函数,\(f = 3^m * 2^n = 3^m * 2^{\frac{x - 3m}{2}}\),可以得到$ln  f $是一个关于m递增的函数,如下公式所示。所以m越大越好,m表示3的个数,也就是说分解的时候尽量分多一些3,分到不能分再分2。
\[ \begin{split} ln\ f &= m * ln3 + \frac{x - 3m}{2} * ln2 \ &= \frac{x}{2} ln \ 2 + (ln\ 3 - \frac{3}{2}ln\ 2)*m \end{split}\]

时间复杂度O(n),空间复杂度O(1)

代码

class Solution(object):
    def integerBreak(self, n):
        """
        :type n: int
        :rtype: int
        """
        if(n == 2 or n == 3):
            return n-1
        res = 1
        while(n>=5):
            n -= 3
            res *= 3
        res *= n
        return res     

出于以下考虑,还可以这么写。
如果n%3 == 0,可以分解成n/3个3,它们的积为\(3^{n/3}\)
如果n%3 == 1,说明和的形式为n/3 * 3 + 1,把其中一个3和单独的1改写为2个2,它们的积为\(3^{n/3-1} * 2 * 2\)
如果n%3 == 2,说明和的形式为n/3 * 3 + 2,它们的积为\(3^{n/3} * 2\)

class Solution(object):
    def integerBreak(self, n):
        """
        :type n: int
        :rtype: int
        """
        if n>=4:
            if n%3 == 0:
                return 3**(n/3)
            if n%3 == 1:
                return 3**(n/3-1)*4
            else:
                return 3**(n/3)*2
        return n-1

343. Integer Break

标签:tput   inline   因子   isp   def   turn   end   object   input   

原文地址:https://www.cnblogs.com/liaohuiqiang/p/9762585.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!