問題:
給你一根長度為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.首先用動態規劃遞迴實現,動態規劃實際上就是用空間效率換時間效率的一種做法:
publicclass
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.採用貪心演算法得到最優解:
publicstatic
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...