AcWing 25. 剪绳子

题目描述

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

每段的绳子的长度记为k[0]、k[1]、……、k[m]。k[0]k[1] … k[m] 可能的最大乘积是多少?

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

样例

输入:8

输出:18

算法

查资料网上搜看的好多都说是动态规划或贪心算法,表示没看懂,我只能是找规律找出来的。

设f(n)代表长度为n的绳子剪成若干段的最大乘积,如果第一刀下去,第一段长度是i,那么剩下的就需要剪n-i,那么f(n)=max{f(i)*f(n-i)},n取1,2,3,......,n-1。下面开始找规律: 

n

i

所有可能切法

n

f(n)

说明

1

 

 

 

 

不用想了,没得切

2

1

1*1=1

 

2(不切)

切1刀最大乘积为1,不切

3

1,2

1*2=2*1=2

 

3(不切)

切1刀最大乘积为2,不切

4

1,3

1*3=3*1=3

 

4(不切)

切1刀最大乘积为4,不切

2

2*2=4

 

5

1,4

1*4=4*1=4

 

 

 

2,3

2*3=3*2=6

5

3*2=6

切1刀最大乘积为6

6

1,5

1*f(5)=f(5)*1=1*2*3=6

 

 

 

2,4

2*4=4*2=8

 

 

 

3,3

3*3=9

6

3*3=9

切1刀最大乘积为9

7

1,6

1*f(6)= f(6)*1=1*3*3=9

 

 

 

2,5

2*f(5)=f(5)*2=2*3*2=12

7

3*4=12

切2刀最大乘积为12

3,4

3*4=4*3=12

切1刀最大乘积为12

8

1,7

1*f(7)=f(7)*1=1*3*4=1*2*2*3=12

 

 

 

2,6

2*f(6)=f(6)*2=2*3*3=18

8

3*3*2=18

切2刀最大乘积为18

切2刀最大乘积为18

3,5

3*f(5)= f(5)*3=2*3*3=18

4,4

4*4=16

 

 

 

9

1,8

1*f(8)=f(8)*1=1*2*3*3=18

 

 

 

2,7

2*f(7)=f(7)*2=2*3*4=24

 

 

 

3,6

3*f(6)=f(6)*3=3*3*3=27

9

3*3*3=27

切2刀最大乘积为27

4,5

4*f(5)=f(5)*4=2*3*4=24

 

 

 

  可以看出当n>=5时才有必要进行切割,且进行切割时优先考虑3,例如n=8时,4*4<3*3*2,因此,n对3取余后只有0,1,2三种情况,余0说明正好3的倍数,余1时,因为3*1<4,所以我们可以取出一个3凑成4来使乘积更大。

大概就是这个,可能这是最笨的理解方法了φ(>ω<*) 

Python3 代码

### Python3 代码
class Solution(object):
    def maxProductAfterCutting(self,length):
        """
        :type length: int
        :rtype: int
        """
        if length == 2:
            return 1
        product = 1
        while(length >= 5):
            product *= 3
            length -= 3
        return product * length

最后附上大神们写的动态规划or贪心算法--剪绳子/切割杆,OVER!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值