从数学角度求解割绳子

从数学角度求解割绳子

#题目来源:https://leetcode.cn/problems/jian-sheng-zi-lcof/
题目不是很难,但是感觉是一个小小的数学问题,所以特意记录了下来。一般来说用数字分析的方法,贪心算法应该也都可以求解。

在数学上来考虑划分情况,借助于一个“经验”:和为4可以分为2x2,和为5可以分为2x3(而大于5本身),6可以分为3x3(大于2x2x2,更大于6本身)…

其实对于任意一个数字 n ≥ 3 n\geq3 n3都可以表示为 2 ∗ i + 3 ∗ j , 其中 i , j ≥ 0 2*i+3*j, 其中i,j\geq0 2i+3j,其中i,j0。而根据上面的规律只需说明: 2 i ∗ 3 j ≥ 2 ∗ i + 3 ∗ j ( 1 ) 2^i*3^j\geq 2*i+3*j (1) 2i3j2i+3j1因为只要这个式子满足,则对于一个更大的n’,总可以表示为 n + n+ n+某一个数字的划分,问题便又回到了之前的情况。

同时对(1)式两端取除以 2 i ∗ 3 j 2^i*3^j 2i3j,只需比较 2 ∗ i 2 i ∗ 3 j + 3 ∗ j 2 i ∗ 3 j ≤ 1 \frac{2*i}{2^i*3^j} + \frac{3*j}{2^i*3^j}\leq1 2i3j2i+2i3j3j1
注意看 2 i 2^i 2i 2 ∗ i 2*i 2i,这是一个指数函数和一次函数(画图比较直观,实在不行就求导看一下),在i=1和i=2时相等, i > 2 i>2 i>2之后 2 i > 2 ∗ i 2^i>2*i 2i>2i 3 j 3^j 3j同理。也就是说左端第一项 ≤ 1 3 j \leq\frac{1}{3^j} 3j1,左端第二项 ≤ 1 2 i \leq\frac{1}{2^i} 2i1,而当i或者j取0的时候,左端对应一项为0,所以左端最大为 1 2 + 1 3 = 5 6 < 1 \frac{1}{2}+\frac{1}{3}=\frac{5}{6}<1 21+31=65<1

上面说明了任意一个数字拆分成只含2和3的组合时能达到最大。下面说明具体拆分的时候的2和3的“分配问题”。

1、当 n = 3 ∗ k , k ≥ 1 n = 3*k, k\geq1 n=3k,k1,取全3最大:如果要添加2进去,先要去除部分3,只能添加的情况是:分段的长度是2和3的公倍数(如6=3+3或者2+2+2),意思是如果单独拿出一个3添加一个2,只后只能再加一个1,显然只会使得乘积变小。而显然在长度为2和3的公倍数情况下,按3划分要比按2划分好(2),所以还是取全3.

2、当 n = 3 ∗ k + 1 , k ≥ 1 n = 3*k+1,k\geq1 n=3k+1,k1,则假设有一部分是取的全三(这一部分如果有2又会出现第一种情况,所以不更改取法),则剩下一个1,而此时判断去掉一个3得到2x2结果好过1x3,所以拿掉一个3,加入两个2。

3、当 n = 3 ∗ k + 2 , k ≥ 1 n=3*k+2,k\geq1 n=3k+2k1,同理假设前面的段取了全3,后面的只剩下一个2,之间乘上去就可以了。

补充说明:(2)式不是显然的,需要说明一下。
假设n可以同时整除2和3,则 n = 2 ∗ i = 3 ∗ j , 其中 i , j ≥ 1 n=2*i=3*j,其中i,j\geq1 n=2i=3j,其中i,j1
现在需要比较 2 i 与 3 j 2^i与3^j 2i3j,只需要比较 2 n 2 与 3 n 3 2^\frac{n}{2}与3^\frac{n}{3} 22n33n,只需要比较 2 1 2 与 3 1 3 2^\frac{1}{2}与3^\frac{1}{3} 221331,而显然
8 = ( 2 1 2 ) 6 < ( 3 1 3 ) 6 = 9 8=(2^\frac{1}{2})^6<(3^\frac{1}{3})^6=9 8=(221)6<(331)6=9

class Solution:
    def cuttingRope(self, n: int) -> int:
        if n <= 3: 
            return n - 1
        i = n // 3
        j = n % 3
        if j == 0: 
            return int(math.pow(3, i))
        if j == 1: 
            return int(math.pow(3, i - 1) * 4)
        if j == 2:
            return int(math.pow(3, i) * 2)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值