剑指offer-67-剪绳子(Python,Go实现)

题目描述

给你一根长度为n的绳子,请把绳子剪成整数长的m段(m、n都是整数,n>1并且m>1,m<=n),每段绳子的长度记为k[1],…,k[m]。请问k[1]x…xk[m]可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。
输入描述:
输入一个数n,意义见题面。(2 <= n <= 60)
输出描述:
输出答案。

算法思路

1 贪心算法
尽可能的分成长度为3的绳子,相当于对3取余,count为可以分成多少个3,num表示余数
(1)num = 1,count - 1 个 3 以及 一个4 相乘
(2)num = 2,count 个 3 以及一个2 相乘
(3)num = 0,count 个 3 相乘
2 动态规划
f(n)= max(f(n - i) * f(i)) i = 1~n/2

代码实现

1 贪心算法

class Solution:
    def cutRope(self, number):
        if number == 2:
            return 1
        if number == 3:
            return 2
        if number == 4:
            return 4
        count = number // 3
        num = number % 3
        if num == 1:
            return 3 ** (count - 1) * 4
        elif num == 2:
            return 3 ** count * 2
        else:
            return 3 ** count
func Solution(number int) int {
     
	// 贪心算法
	if number == 2 {
     
		return 1
	}
	if number == 3 {
     
		return 2
	}
	if number == 4 {
     
		return 4
	}
	count := float64(number / 3)
	num := number % 3
	if num == 1 {
     
		return int(math.Pow(3, count - 1) * 4.0)
	} else if num == 2 {
     
		return int(math.Pow(3, count) * 2.0)
	} else {
     
		return int(math.Pow(3, count))
	}
}

2 动态规划

class Solution:
    def cutRope(self, number):
        if number == 2:
            return 1
        if number == 3:
            return 2
        dp = [0] * (number + 1)
        dp[1] = 1
        dp[2] = 2
        dp[3] = 3
        for n in range(4, number + 1):
            for i in range(1, n / 2 + 1):
                dp[n] = max(dp[n], dp[n - i] * dp [i])
        return dp[number]
func Solution1(number int) int {
     
	if number == 2 {
     
		return 1
	}
	if number == 3 {
     
		return 2
	}
	dp := make([]float64, number + 1)
	dp[1] = 1
	dp[2] = 2
	dp[3] = 3
	for n := 4; n <= number; n++ {
     
		for i := 1; i <= n / 2; i++ {
     
			dp[n] = math.Max(dp[n], dp[n - i] * dp[i])
		}
	}
	return int(dp[number])
}

你可能感兴趣的:(算法)