343-Integer-Break
Last updated
Was this helpful?
Last updated
Was this helpful?
给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化。 返回你可以获得的最大乘积。
测试用例:
示例 1: 输入: 2 输出: 1 解释: 2 = 1 + 1, 1 × 1 = 1。
示例 2: 输入: 10 输出: 36 解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36。
说明: 你可以假设 n 不小于 2 且不大于 58。
这道题虽然打着动态规划的标签,但实际上用数学方法更快。
数学方法:
对于一个数num=x+y
拆成两个整数的话,x
和y
的差值越小x
与y
的乘积才会越大。例如增大x
与y
的差值(假设x>=y)。num=(x+1)+(y-1)
,(x+1)*(y-1)=xy-(x-y)-1<xy
。所以如果要把一个数拆成两个两个整数,那么这两个数的差值越小越小,最好是x==y
。
那么把一个数拆成n个整数的是一样的,最好的情况是这n个数相等。
那么最完美的情况就是每个拆分后的数为(n/x)。最后的乘积为(n/x)^n
。对该函数求导,当x=n/e
时乘积最大。那么每段的长度为e
时,乘积最大。离e
最近的整数为3
。所以我们需要把数n
拆成尽可能多的3。
但是上述规则只适用于n>=4,当n<=4时,拆分后的最大乘积为(n-1)。
暴力递归方法:
对于一个数n
我们可以拆成两部分x
和y
。我们可以选择拆分或者不拆分x
或者y
。那么拆分后的最大乘积就会有四种情况(假设x
拆分后的最大乘积为left
,y
拆分后的最大乘积为right
):
x*y
x*right
left*right
left*y
最后拆分后的最大值在这四者中选一个最大的。
那么对于数n
,我们有n-1
个拆分点。又是拆分点,跟字符串的dp有点像了奥。
数学方法:
递归方法:
动态规划:
拆分整数、割绳子都是一类问题。