整数划分--思考问题背后的数学原理
2018-08-29 本文已影响0人
mbinary
今天在 leetcode 做动态规划的题, 做到一道整数划分的题目如下
Given a positive integer n, break it into the sum of at least two positive integers and maximize the product of those integers. Return the maximum product you can get.
Example 1:
Input: 2
Output: 1
Explanation: 2 = 1 + 1, 1 × 1 = 1.
这个用动态规划很容易写出代码如下,
class Solution:
def integerBreak(self, n):
"""
:type n: int
:rtype: int
"""
self.dic={1:1}
for i in range(2,n+1):
mx = 1
for j in range(1,i):
prod = j*self.dic[i-j]
mx =max(mx,prod,j*(i-j))
self.dic[i] = mx
return self.dic[n]
后来想到, 这不就是均值不等式吗? 给定和, 求积最大, 即
如果先不考虑整数的话,易知当所有数相等时最大,但是注意这里并不知道数的个数 k, 所以设各个数为 x, 有 n/x个
要求出 x, 可以用导数. 各个数的积即为 , 求其最大值
求导得
易知当 x = e 的时候函数 f(x)有最大值
下面考虑整数, x=2 或者 3
即比较 ,
的增长速度, 这很简单了, 其实都是指数函数, 换个形式即为
,
由于 n > 0 , 底数大的增长快,
计算得
所以, 尽量将整数 n 分成 3即可,
于是原题目有了下面的非动态规划解法
class Solution(object):
def integerBreak(self, n):
"""
:type n: int
:rtype: int
"""
if n<5:
return [0, 0, 1, 2, 4][n]
x = n % 3
if x == 0:
return 3 ** (n // 3)
if x == 1:
return 3 ** (n // 3 - 1) * 4
return 3 ** (n // 3) * 2
本来是个很简单的题, 但是给我的感觉就是:
动态规划是种系统的方法, 它依靠计算机的算力对问题直接求解, 不用了解其背后的数学原理.
而有时候, 如果我们跳出常规思维, 思考问题背后的数学规律, 就可能发现更加好的解法. 更加完备,快速, 健壮.