本文主要是介绍[Leetcode 343]. 整数拆分 [剑指offer] 面试题14- I. 剪绳子,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化。 返回你可以获得的最大乘积。
给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m、n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[1]…k[m-1] 。请问 k[0]k[1]…*k[m-1] 可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。
动态规划
主要思路:在已知长度为n的绳子最大乘积的基础上,长度n+1绳子的最大乘积可能来源依赖于前面已知求解。
定义辅助数据结构:记长度为n的绳子最大乘积为s[n],初始化s = [0]*(n+1), 显然 s[2] = 1。
假设当前处理长度为i的绳子最大乘积问题:
从i中截取一块长度为j的绳子,剩余长度i-j的最大乘积为s[i-j],即最后一段长度为j的方案带来的乘积为j*s[i-j];
由于我们假定长度i-j绳子最大乘积为s[i-j]的前提是要求i-j必须进行分割(m>1),然而对于从i中截取j这一事件本身已经满足分割要求,所以上述取最值还需增加一个补丁:即仅对长度i进行i-j和j两段分割的判断。
状态转移方程
s[i] = max(s[i], j*(i-j), j*s[i-j])
代码:
class Solution:def cuttingRope(self, n: int) -> int:s = [0 ] * (n+1) s[2] = 1for i in range(3, n+1):for j in range(0, i):s[i] = max(s[i], j*(i-j), j*s[i-j]) return s[n]
这篇关于[Leetcode 343]. 整数拆分 [剑指offer] 面试题14- I. 剪绳子的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!