剪繩子 牛客網-劍指Offer_編程題


題目描述

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

題目分析

首先,將該題目可以建模成:

(一)當不考慮未知數是否為整數的情況

 可知,首先要找到最佳的m,再找到最佳的m個段長。若m固定的話,怎樣將n分配到m段才能讓這m段的乘積最大呢?很容易想到,當n均勻分配到m段時,m段長的乘積最大,這也是可以證明得到的。

 假設m=2,則x+y=n,f(x,y)=x*y=x*(n-x)=nx-x2,對於這樣一個二次函數,它具有最小值n2/4,對應x=y=n/2,這個大家都知道。那么推廣到m未知的情況,是怎么樣的?
 
 根據

 

 可以消元得到

 

 對函數求偏導並令所有偏導等於0,即可得到極值:

...

 

 

 化簡得到:

...

 

即:

 

那么可知

此時f函數在m固定的情況下具有最大值,那么其實m也是個未知數,如何確定m使得f函數最大呢?

我們又可以使用求導令其等於0的方法,不過我們可以稍稍變換一下函數使其更好求導,即函數前加個ln:

求出了lnf的極值點,那么也就求出了f的極值點:

 

可得:

 

故可知:上式情況下函數f具有最大值

(二)考慮到未知數應為整數的情況

根據我們的建模公式,咱們的未知數都為整數,而在上一步,我們求得的解很可能產生小數,所以我們需要調整。

m的范圍最好是在n/e左右,那么就考慮m要么為n/e左邊的整數,要么為其右邊的整數。

同理,分出來的段長要么為2,要么為3。

python編程實現 

1 for i in range(2, 61):
2     m = i/math.e
3     m1 = int(m) if int(m) > 1 else 2
4     m2 = m1 + 1 if int(m) > 1 else 2
5     c1 = int(i/m1)
6     c2 = int(i/m2)
7     r3 = ((c1+1) ** (i - c1 * m1)) * (c1 ** (m1 - i + c1 * m1))
8     r4 = ((c2+1) ** (i - c2 * m2)) * (c2 ** (m2 - i + c2 * m2))
9     print(r3 if r3 >= r4 else r4)

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM