動態規劃之割繩子

2021-08-17 18:15:58 字數 1418 閱讀 2961

題目:給你一根長度為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.

思路:採用自底向上的動態規劃方法。設f(n)代表長度為n的繩子剪成若干段的最大乘積,如果第一刀下去,第一段長度是i,那麼剩下的就需要剪n-i,那麼f(n)=max。而f(n)的最優解對應著f(i)和f(n-i)的最優解,假如f(i)不是最優解,那麼其最優解和f(n-i)乘積肯定大於f(n)的最優解,和f(n)達到最優解矛盾,所以f(n)的最優解對應著f(i)和f(n-i)的最優解。首先,剪繩子是最優解問題,其次,大問題包含小問題,並且大問題的最優解包含著小問題的最優解,所以可以使用動態規劃求解問題,並且從小到大求解,把小問題的最優解記錄在陣列中,求大問題最優解時就可以直接獲取,避免重複計算。

n<2時,由於每次至少減一次,所以返回0。n=2時,只能剪成兩個1,那麼返回1。n=3時,可以剪成3個1,或者1和2,那麼最大乘積是2。當n>3時,就可以使用公式進行求解。

f(4)=max

f(5)=max

...f(n)=max

因為需要保證f(i)f(n-i)不重複,就需要保證i<=n/2,這是乙個限制條件,求1~n/2範圍內的乘積,得到最大值

package dongtaiguihua;

//給你一根長度為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.

//採用動態規劃解法,狀態轉移方程為f(n)=max

public class geshengzi

if(length<2) return 0;

if(length==2) return 1;

if(length==3) return 2;

//建立陣列儲存子問題最優解

// 陣列中的第i個元素表示把長度為i的繩子剪成若干段後各段長度乘積的最大值。

int f=new int[length+1]; //0-length,共length+1

//這些情況下,不剪的時候長度比剪的時候長,所以作為初始條件

//這些都是子問題最優解,因為是子問題,所以這些情況可以不剪,因為可以看成它是分割後的一部分

f[0]=0;

f[1]=1;

f[2]=2;

f[3]=3;

for(int i=4;i<=length;i++)

}f[i]=max;

}return f[length];

}}

動態規劃 剪繩子

include include include using namespace std 題目 給你一根長度為n的繩子,請把繩子剪成m段 m和n都是整數,n 1並且m 1 每段繩子的長度記為k 0 k 1 k m 請問k 0 k 1 k m 可能的最大乘積是多少?例如,當繩子的長度為8時,我們把它剪成...

剪繩子動態規劃

題目 給你一根長度為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.我們有兩種不同的方法解決這...

剪繩子(貪心 動態規劃)

準備找工作,開始刷題,牛客劍指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的三段,此時得到...