動態規劃與貪心演算法 剪繩子問題

2022-09-06 06:54:07 字數 1829 閱讀 5551

問題:

給你一根長度為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.動態規劃

求乙個問題的最優解(最大值或最小值),而且該問題能夠分解成若干子問題,並且子問題之間還有重疊的更小的子問題,可以考慮動態規劃

(1) 分析是否能把大問題分解成小問題

(2) 分解後的每個小問題存在最優解

(3) 小問題的最優解組合起來能得到整個問題的最解

2.貪心演算法求解:

每一步都可以做出乙個貪婪的選擇,基於這個選擇,確定能夠得到最優解

1. 貪心演算法在對問題求解時,不從整體最優上加以考慮,他所做出的是在某種意義上的區域性最優解

2. 選擇的貪心策略必須具備無後效性,即某個狀態以前的過程不會影響以後的狀態,只與當前狀態有關

3. 題目貪心策略:當n>=5時,盡可能多地剪長度為3的繩子;當剩下的繩子長度為4時,把繩子剪成兩段長度為2的繩子

1.首先用動態規劃遞迴實現,動態規劃實際上就是用空間效率換時間效率的一種做法:

public

class

test

//長度為2時,要求剪下段數m>1,所以最大是1x1=1

if(n==2)

//長度為3時,要求剪下段數m>1,所以最大是1x2=2

if(n==3)

//儲存長度從 0-n 的最大結果

int result=new

int[n+1];

result[0]=0;

result[1]=1;

result[2]=2;

result[3]=3;

//自底向上開始求解

int max=0;

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

//更新表中的f(i)=max(f(j)·f(i-j))

result[i]=max;}}

max=result[n];

return

max;

}}

2.採用貪心演算法得到最優解:

public

static

int getmaxvalue(int

n)

if(n==2)

if(n==3)

//先求出長度為3的段一共有多少段

int countofthree=n/3;

//再看除了長度為3的段,還剩下多少公尺,如果還剩1公尺則表示有(n-1)個3和乙個4,

//所以要把上一步算出來的3的個數減1,把最後的4剪成兩段長度為2的繩子

if(n-countofthree*3==1)

//當剩下的繩子長度為4時,把繩子剪成兩段長度為2的繩子

int countoftwo=(n-countofthree*3)/2;

//計算所有的3的countofthree次方,再乘以剩下2的countoftwo次方

return (int) ((math.pow(3, countofthree))*(math.pow(2, countoftwo)));

}

剪繩子(動態規劃 貪心演算法)

劍指offer 中題14 給你一根長度為n的繩子,請把繩子剪成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。第...

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

給你一根長度為 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.思路 動態規劃法 package jianzhi offer public class cut shengzi private static intmatproductaftercutting 1 int length if length 2 if length 3 將最優解儲存在陣列中 int...