動態規劃之二 剪繩子問題

2021-08-18 19:46:55 字數 1429 閱讀 9687

問題:現有一根長度為n的繩子,需要你剪成m段,使m段的乘積最大。(其中m、n都為整數,剪成的每段長度也為整數,n已知,m未知)

當我們遇到乙個大規模問題時,總是習慣把問題的規模變小,這樣便於分析討論。

我們從最簡單的情況進行分析:

當繩子的長度n=1時,我們至少需要剪繩子一次,這時乘積為0;

當繩子的長度為n=2時,剪一次後繩子的兩段長度為分別為1、1,這時乘積為1*1=1;

當繩子的長度為n=3時,我們對繩子有兩種方式,其一為剪成三段,它們的長度分別為1、1、1,乘積為1*1*1=1;其二為剪成兩段,它們的長度分別為1、2,乘積為1*2=2,則最終乘積取這兩種方式中的最大值為max(1*1*1,1*2)。

當繩子的長度為n=4時,我們對繩子有三種方式,其一為剪成四段,它們的長度分別為1、1、1、1.乘積為1*1*1*1=1;其二為剪成兩段,他們的長度為1、3.乘積為1*3=3,其三為剪成三段,它們的長度分別為1、2、1,乘積為1*2*1=2;其四為剪成兩段,它們的長度分別為2、2,乘積為2*2=4;則最終乘積取上面結果中最大值max(1*1*1*1,1*3,1*2*1, 1*2)。

現在我們要用數學符號表示剪繩子的最大乘積的狀態,使用f(n)表示繩子長度為n剪成若干段的最大乘積狀態,由上面分析可知,

當n=1時,f(1)=0;

當n=2時,f(2)=1*1=1;

當n=3時,f(3)=max(1*1*1,1*2)=2

當n=4時,f(4)=max(1*1*1*1,1*3,1*2*1, 1*2)=4

我們知道使用動態規劃求解問題,需要具備其中乙個性質:最優子結構性質,也即我們需要知道狀態轉移函式。通過對上述狀態的描述我們可以進一步簡化中間環節:

當n=1時,f(1)=0;

當n=2時,f(2)=1;

當n=3時,f(3)=f(1)*f(2)=2

當n=4時,f(4)=max(f(1)*f(3),f(2)*f(2))=4

當n=5時,f(5)=max(f(1)*f(4),f(2)*f(3))=6

f(n)=max(f(1)*f(n-1), f(2)*f(n-2) , f(3)*f(n-3) , ... , f(i)*f(n-i) )

由此,我們可以知道狀態轉移函式為:f(n)= max( f(i) * f(n-i)  ) , 其中i的取值範圍為(i>0&&i<=n/2)。

程式如下所示:

#includeusing namespace std;

#define size 100 //**的大小

int line_max(int a,int n)

int main() ;//對**進行初始化,用來儲存長度為i的最大乘積值

int n;

cin >> n;

cout << line_max(table, n) << endl;

}

動態規劃 剪繩子

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的三段,此時得到...