【剑指Offer】 67.剪绳子

题目描述

给你一根长度为n的绳子,请把绳子剪成整数长的m段(m、n都是整数,n>1并且m>1),每段绳子的长度记为k[0],k[1],…,k[m]。请问k[0]xk[1]x…xk[m]可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。

用例

输入输出分析
00不能分割
11不能分割
21分为1,1的两段
32分为2,1的两段
44分为2,2的两段
56分为2,3的两段
69分为3,3的两段
712分为2,2,3的三段
818分为2,3,3的三段
927分为3,3,3的三段
1036分为2,2,3,3的四段
1154分为2,3,3,3的四段
1281分为3,3,3,3的四段
13108分为2,2,3,3,3的五段
14162分为2,3,3,3,3的五段

N >0 N = n1 + n2 + n3+…+nk
结论:要使最后的乘积最大,分出的数有以下特征:
1.只包含2或3;
2.且2的个数不会超过2个
证明:
1.假设 ni >= 5, 3 ∗ ( n i − 3 ) 3*(ni-3) 3(ni3) >= ni? 一定!因为:2*ni >= 9,所以所有分解的数字中不会有超过5的
2.ni = 4, 4= 2 ∗ 2 2*2 22 所以不会包含4
3.为什么分解2的个数不会超过2呢?因为 2 ∗ 2 ∗ 2 2*2*2 222 < 3 ∗ 3 3*3 33,分解两个三的效果比分解成三个二的效果更佳。

1-归纳法

# -*- coding:utf-8 -*-
class Solution:
    def cutRope(self, number):
        # write code here
        if number == 0:
            return 0
        elif number in (1, 2):
            return 1
        elif number == 3:
            return 2
        return self.subFunction(number)

    def subFunction(self, number):
        a = []
        while number:
            if number % 3 == 0:
                a.append(3)
                number = number - 3
            else:
                a.append(2)
                number = number - 2
        maxV = 1
        for i in a:
            maxV *= i
        return maxV

s = Solution()
res = s.cutRope(14)
print(res)

2.贪心算法

class Solution:
    def cutRope(self, number):
        # write code here
        res=1
        if number<=1:
            return 0
        elif number<=2:
            return 1
        elif number<=3:
            return 2
        elif number>3:
            if number%3==0:
                res=3**(number//3)
            elif number%3==1:
                res=3**(number//3-1)*4
            else:
                res=3**(number//3)*(number%3)
        return res

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值