整数划分 -- 思考问题背后的数学原理

今天在 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]

后来想到, 这不就是均值不等式吗? 给定和, 求积最大, 即

a1+a2ak=i=1kai=n,findmax(i=1kai) a 1 + a 2 … a k = ∑ i = 1 k a i = n , find m a x ( ∏ i = 1 k a i )

如果先不考虑整数的话, 易知当所有数相等时最大, 但是注意这里并不知道数的个数 k, 所以设各个数为 x, 有 n/x 个
要求出 x, 可以用导数. 各个数的积即为 xnx x n x , 求其最大值
f(x)=xnx,x>0 f ( x ) = x n x , x > 0

求导得
f(x)=nxnx2(1lnx) f ′ ( x ) = n x n x − 2 ( 1 − l n x )

易知当 x = e 的时候函数 f(x) 有最大值

下面考虑整数, x=2 或者 3

即比较 2n2 2 n 2 , 3n3 3 n 3
的增长速度, 这很简单了, 其实都是指数函数, 换个形式即为
2n 2 n , 33n 3 3 n

由于 n > 0 , 底数大的增长快,

计算得
2=1.414,33=1.442 2 = 1.414 , 3 3 = 1.442
所以, 尽量将整数 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

本来是个很简单的题, 但是给我的感觉就是:
** 动态规划是种系统的方法, 它依靠计算机的算力对问题直接求解, 不用了解其背后的数学原理.
而有时候, 如果我们跳出常规思维, 思考问题背后的数学规律, 就可能发现更加好的解法. 更加完备, 快速, 健壮.**

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值