剑指Offer-剪绳子

86 阅读1分钟

题目

给你一根长度为 nn 绳子,请把绳子剪成 mm 段(mm、nn 都是整数,2≤n≤582≤n≤58 并且 m≥2m≥2)。

每段的绳子的长度记为 k[1]、k[2]、……、k[m]k[1]、k[2]、……、k[m]。

k[1]k[2]…k[m]k[1]k[2]…k[m] 可能的最大乘积是多少?

例如当绳子的长度是 88 时,我们把它剪成长度分别为 2、3、32、3、3 的三段,此时得到最大的乘积 1818。

样例 输入:8

输出:18

解析(参考y总)

将一个正整数N拆分成若干个正整数只有有限个拆法,所以存在最大乘积。设N = n1 + n2 + ... + nk,且 n1 * n2 * ... * nk是最大乘积:

  1. 1显然不会在里面
  2. 如果某i有ni>=5可以将ni拆分成3 + (ni - 3),且有3 * (ni - 3) = 3 * ni - 9 > ni
  3. 若ni = 4,拆分成2 + 2乘积不变,所以可假设没有4
  4. 如果有三个以上2,那么3 * 3 > 2 * 2 * 2,所以换成3乘积更大 ** 所以,尽量选取更多的3,直到剩下2/4, 用2 **

代码

Go

func maxProductAfterCutting(n int) int {
    if n <= 3 {
        return 1 * (n - 1)
    }
    
    ans := 1
    if n % 3 == 1 {
        ans *= 4
        n -= 4
    }
    
    if n % 3 == 2 {
        ans *= 2
        n -= 2
    }
    
    for n > 0 {
        ans *= 3
        n -= 3
    }
    
    return ans
}