演算法 動態規劃篇 第5節 剪繩子問題

2021-10-05 09:37:05 字數 2610 閱讀 9672

【演算法】【動態規劃篇】第1節:0-1揹包問題

【演算法】【動態規劃篇】第2節:數字矩陣問題

【演算法】【動態規劃篇】第3節:數字三角形問題

【演算法】【動態規劃篇】第4節:硬幣找零問題

【演算法】【動態規劃篇】第5節:剪繩子問題

【演算法】【動態規劃篇】第6節:最低票價問題

【演算法】【動態規劃篇】第7節:最長子串問題

【演算法】【動態規劃篇】第8節:最大正方形問題

【演算法】【動態規劃篇】第9節:乘積最大子陣列問題

【演算法】【動態規劃篇】第10節:最長連續序列問題

"""

剪繩子問題

給你一根長度為n的繩子,請把繩子剪成m段(m,n都是整數),每段繩子的

長度記為k[0],k[1],k[2]…. 請問如何剪繩子使得k[0],k[1],k[2]

的乘積最大

例如 繩子長度8 最大乘積18 = 2*3*3

輸入:n=8

輸出:18

"""

本題的解法與硬幣找零問題大同小異,可以閱讀【演算法】【動態規劃篇】第4節:硬幣找零問題,加深對此類問題的理解。

乙個模型:

三個特徵:

無後效性:

最優子結構:

綜上所述,本問題滿足乙個模型、三個特徵,所以可以使用動態規劃來求解。

當然,凡是能用動態規劃解決的問題,都可以用回溯思想來暴力求解,具體實現**在文末給出,更多關於回溯思想的應用,可以參照:【演算法】【回溯篇】第7節:0-1揹包問題

1. 動態規劃解法

class

solution()

:def

dp(self, n)

:"""

使用動態規劃求解剪繩子問題,思路:維護乙個長為n的陣列,自底向上求解最優值!!!

:param n: 繩子長度

:return: 最大乘積值

"""if n <2:

# 長度為1,無法剪

return

0if n ==2:

# 長度為2,只能剪成1*1

return

1if n ==3:

# 長度為3,剪成2*1 > 1*1*1

return

2 res =[-

1]*(n +1)

# 初始化陣列

res[0]

=1# 約定f(0)=1

for i in

range(1

, n +1)

:# 依次計算f(1)--f(8)

res[i]

=max([

(j +1)

* res[i - j -1]

for j in

range

(i)]

)return res[-1

]def

main()

: n =

8 client = solution(

)print

(client.dp(n)

)if __name__ ==

'__main__'

: main(

)

執行結果:

18
2. 回溯解法

class

solution()

:def

trackback

(self, n)

:"""

使用回溯法求解剪繩子問題

:param n: 繩子長度

:return: 最大乘積值

"""if n <2:

# 長度為1,無法剪

return

0if n ==2:

# 長度為2,只能剪成1*1

return

1if n ==3:

# 長度為3,剪成2*1 > 1*1*1

return

2 self.max_v = n # n大於0,所以初值設為n

self.helper(n,1)

# 回溯暴力求解

return self.max_v

defhelper

(self, n, v)

:"""一次遍歷完所有可能"""

if n ==0:

# 當繩長為0時進行結算

if self.max_v < v:

self.max_v = v

return

for i in

range(1

, n +1)

:# 每次分段的長度介於[1, n]

self.helper(n - i, v * i)

defmain()

: n =

8 client = solution(

)print

(client.trackback(n)

)if __name__ ==

'__main__'

: main(

)

執行結果:

18

動態規劃與貪婪演算法 剪繩子

題目 給你一根長度為n繩子,請把繩子剪成m段 m n都是整數,n 1並且m 1 每段的繩子的長度記為k 0 k 1 k m k 0 k 1 k m 可能的最大乘 積是多少?例如當繩子的長度是8時,我們把它剪成長度分別為2 3 3的三段,此 時得到最大的乘積18。1 動態規劃 因為不知道剪在哪個位置是...

剪繩子(動態規劃 貪心演算法)

劍指offer 中題14 給你一根長度為n的繩子,請把繩子剪成m段 m n都是整數,n 1並且m 1 每段繩子的長度記為k 0 k 1 k m 請問k 0 x k 1 x x k m 可能的最大乘積是多少?例如,當繩子的長度是8時,我們把它剪成長度分別為2 3 3的三段,此時得到的最大乘積是18。第...

動態規劃與貪心演算法 剪繩子問題

問題 給你一根長度為n繩子,請把繩子剪成m段 m n都是整數,n 1並且m 1 每段的繩子的長度記為k 0 k 1 k m k 0 k 1 k m 可能的最大乘積是多少?例如當繩子的長度是8時,我們把它剪成長度分別為2 3 3的三段,此時得到最大的乘積18。求解 1.動態規劃 求乙個問題的最優解 最...