剪繩子 演算法 從剪繩子看動態規劃和貪心演算法

2021-10-14 16:00:45 字數 1425 閱讀 9065

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

長度記為 k[0],k[1]...k[m-1] 。請問 k[0]*k[1]*...*k[m-1] 可能的最大乘積是多少?例如,

當繩子的長度是8時,我們把它剪成長度分別為2、3、3的三段,此時得到的最大乘積是18。

//普通的動態規劃解法(帶備忘錄的遞迴,也可以用迴圈抒寫)時間複雜度1+2+3+...+n-1 :o(n^2)

//空間複雜度o(n)

//狀態轉移方程:d[n]=max(i*d[n-1]) i=1...n-1 d[n] 表示n長度的繩子的最大值

class solution

d = new int[n + 1];

return dfs(n);

}private int dfs(int n)

if (d[n] != 0) else

}d[n] = max;

return max;}}

}

//是不是還可以優化?

每次我們求n的時候都從i*d[n-1]) i=1...n-1 裡找出最大值。

能不能有種策略可以直接得出最大值。

貪心演算法的核心就是:能被證明正確的選擇策略,這就是和動態規劃不一樣的地方。

我們知道:

所以將繩子切成相同段的繩子時,繩子的乘積最大。但是到底切成幾段相等的呢?

這裡就不詳細證明:證明可參考:

直接給出最後答案:

盡可能將繩子以長度3等分為多段時,乘積最大。

我們可以直觀了解一下:

比如:

1:1

2:2

3:3

4:2*2

5:2*3

6:3*3 並不是2*2*2

7:3*2*2 不是 3*3*1

8:3*3*2

切分的規則就是:

最優: 3 。把繩子盡可能切為多個長度為 3的片段,留下的最後一段繩子的長度可能為 0,1,2 三種情況。

次優: 2 。若最後一段繩子長度為 2 ;則保留,不再拆為 1+11+1 。

最差: 1。若最後一段繩子長度為 1;則應把乙份 3+1 替換為 2 ×2

class solution 

if(n==2)

if(n==3)

int a=n/3;

int f=n%3;

if(f==0) else if(f==1) else }}

動態規劃 剪繩子

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.我們有兩種不同的方法解決這...

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

題目 給你一根長度為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 動態規劃 因為不知道剪在哪個位置是...