題目描述
給你一根長度為你的繩子,請把繩子剪成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。
動態規劃
尋找規律f(n
)=ma
x(f(
i)∗f
(n−i
))
f(n)=max(f(i)*f(n-i))
f(n)=m
ax(f
(i)∗
f(n−
i)):
演算法時間複雜度o(n長度n = 0時,最大乘積也為0;
長度n = 1時,因為必需剪一刀,所以最大乘積也為0;
長度n = 2時,最大乘積為1x1=1;
長度n = 3時,最大乘積為1x2=2;
以上幾種情況比較特殊,需要單獨討論。
長度n = 4時,有兩種可能1x3=3和2x2=4,最大乘積為4;
長度n = 5時,有三種可能1x4=4、2x3等於6,最大乘積為6。
到這裡,我們似乎可以總結出乙個規律來解決問題:
從長度4開始,我們都可以將繩子看作剪成兩段,也就是將當前問題變成兩個子問題;
然後這兩個子問題,我們在前面必然已經討論過了。
例如,長度等於5時,可以看作1和4的子問題,1的最優解是1(這裡不需要剪),4的最優解是4,因此1x4=4;
同理也可以看作2和3的子問題,2的最優解是2(同樣不需要剪),3的最優解是3(也不需要剪),所以2x3=6;
我們只需要找出所有組合中最大的乙個即可。
ps:1、2、3作為子問題時不需要剪,這也是我們為什麼特殊討論的原因。
2)
o(n^2)
o(n2
),空間複雜度o(n
)o(n)
o(n)
。
貪婪演算法def
cutting
(length)
:if length <2:
return
0if length ==2:
return
1if length ==3:
return
2
products =[0
,1,2
,3]for i in
range(4
, length +1)
: max_product =
0# i必然由i-1, i-2 ,i-3
for j in
range
(i-3
, i)
: product = products[j]
* products[i-j]
if product > max_product:
max_product = product
return products[length]
if __name__ ==
"__main__"
(cutting(8)
)
上題的時間和空間複雜度還是過大了,能不能再有一種方法簡化呢?
其實我們可以按以下策略剪繩子:當 n >= 5時,盡可能多地剪長度為3的繩子。
時間和空間複雜度都為o(1當 n >= 5時,我們可證 3(n-3)>=n 且 3(n-3) >= 2(n-2),因此應該竟可能多剪長度為3的繩子。
ps:我們的討論範圍始終在1,2,3,因為某種意義上,這3個數是這個問題的「基數」;
4可以看作的2和2或1和3的組合,比4大的數同理,因此不要問為什麼不盡量剪成長度為4。
)o(1)
o(1)
。
2019.8.20 動態規劃的範圍從(1,i)為(i-3,i)def
cutting
(length)
:if length <2:
return
0if length ==2:
return
1if length ==3:
return
2# 剪成3的段數
times_of_3 = length //
3# 2x2比1x3更好
if length %3==
1:times_of_3 -=
1#剪成2的段數
times_of_2 =
(length -
3*times_of_3)//2
return(3
**times_of_3)*(
2**times_of_2)
if __name__ ==
"__main__"
(cutting(5)
)
劍指offer 14 剪繩子
分析 本題可以用動態規劃,也可以用貪心法。動態規劃 設f n 表示當繩子長n時可以得到的最大乘積,那麼假設在i處切一刀,就會得到數學式子f n max f i f n i 02等於4,但是當n大於等於5時,我們就要拆成盡可能多的3和剩下的2。如果要證明,我們可以證明當n大於5時,有3 n 3 2 n...
劍指offer 14 剪繩子
這種文章網上很多,沒什麼營養,我只是自己記錄一下。雖然現在不找工作了,但以後演算法能力肯定需要加強,想著能不能每天堅持一道題,其實真做起來還有點難 劍指offer以前都是邊看答案邊記下來,現在能不能靠自己寫出來呢。時間複雜度為o n2 空間複雜度為o n 有一點要注意,m不是乙個給定的引數。思路是,...
劍指Offer 14 剪繩子
nowcode 把一根繩子剪成多段,並且使得每段的長度乘積最大。n 2 return 1 2 1 1 n 10 return 36 10 3 3 4 盡可能多剪長度為 3 的繩子,並且不允許有長度為 1 的繩子出現。如果出現了,就從已經切好長度為 3 的繩子中拿出一段與長度為 1 的繩子重新組合,把...