長さnのロープを与えるには、ロープを整数長のmの長さにカットしてください(mおよびnは整数、n> 1およびm> 1)。ロープの各長さの長さはk [0]、k [1] ... k [m]。k [0] * k [1] * ... * k [m]の可能な最大積は何ですか?たとえば、ロープの長さが8の場合、ロープをそれぞれ長さ2、3、3の3つのセクションにカットします。このとき得られる最大の積は18です。
例1:
入力:2
出力:1
説明:2 = 1 + 1、1×1 = 1
例2:
入力:10
出力:36
説明:10 = 3 + 3 + 4、3×3×4 = 36
ヒント:
2 <= n <= 58
注:この質問はメインステーション343の質問と同じです:https://leetcode-cn.com/problems/integer-break/
ソース:LeetCode
リンク:https ://leetcode-cn.com/problems/jian-sheng-zi-lcof
著作権は控除ネットワークに属しています。商用転載の正式な許可書に連絡し、非商用転載の出典を明記してください。
アイデア1:暴力
各数値から1を引いた値について、各数値を減算した後、逆アセンブルを続行するかどうかのテストを開始し、どれが最大値かを確認します。
これは多くの重複値を直接計算するので、メモリ配列を使用して計算された数をマークすることを検討できます。
class Solution:
def cuttingRope(self, n: int) -> int:
def fun(n):
if n == 2:
return 1
if f[n] != 0:
return f[n]
res = -1
for i in range(1, n):
res = max(res, max(i * fun(n - i),i * (n - i)))
f[n] = res
return res
# 记忆数组
f = [0 for _ in range(n+1)]
return fun(n)
アイデア2:動的プログラミング(dp)
これは、動的プログラミングを使用して実行できます。動的変換の式は、dp [i] = max(dp [i]、dp [j] * dp [i-j]です。ここで、iは現在の長さ、jは減算された長さです。
タイトルにはm> 1が必要なため、カットする必要があります。2と3の場合は影響があり、特別な判断が必要です。他の一部としてカットするdp [2] = 2、dp [3] = 3、他の人をできるだけ大きくするため。
class Solution:
def cuttingRope(self, n: int) -> int:
if n == 2:
return 1
elif n == 3:
return 2
dp = [0 for _ in range(59)]
dp[2] = 2 # 作为分割后的单元时可以不切
dp[3] = 3
for i in range(4, n+1):
for j in range(1, i//2+1):
dp[i] = max(dp[i], dp[i-j] * dp[j])
return dp[n]
dp別の書き方
class Solution:
def cuttingRope(self, n: int) -> int:
dp = [0 for _ in range(n + 1)] # dp[0] dp[1]其实没用
dp[2] = 1 # 初始化
res = -1
for i in range(3, n + 1):
for j in range(i):
dp[i] = max(dp[i], max((i - j) * j, j * dp[i - j]))
return dp[n]
作者:z1m
链接:https://leetcode-cn.com/problems/jian-sheng-zi-lcof/solution/xiang-jie-bao-li-di-gui-ji-yi-hua-ji-zhu-dong-tai-/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。