1. 程式人生 > >面試題14:剪繩子(動態規劃,貪心演算法)

面試題14:剪繩子(動態規劃,貪心演算法)

一、題目:

一根長度為n的繩子,剪成m段,m,n都大於1,且都為整數,每段長度記為k[0],k[1]…,k[m].求k[0]*k[1]…*k[m]可能的最大乘積

1.1解法:

兩種不同的方法解決這個問題,先用常規的需要O(n²)時間和O(n)空間的動態規劃,接著用只需要O(1)的時間和空間的貪心演算法。

二、動態規劃:

(1)是求最優解問題,如最大值,最小值;
(2)該問題能夠分解成若干個子問題,並且子問題之間有重疊的更小子問題。

2.1通常按照如下4個步驟來設計一個動態規劃演算法:

(1)刻畫一個最優解的結構特徵;
(2)遞迴地定義最優解的值;
(3)計算最優解的值,通常採用自底向上的方法;
(4)利用計算出的資訊構造一個最優解。

2.2用動態規劃分析問題

首先定義函式f(n)為把長度為n的繩子剪成若干段後各段長度乘積的最大值。在剪第一刀的時候,我們有n-1中可能的選擇,也就是剪出來的第一段繩子可能長度為1,2,…,n-1。因此f(n) = max(f(i) * f(n-i))。其中0<i<n。

2.3程式碼實現:

int maxProductAfterCutting_Solution(int length)
{
	//繩子在3米以內,直接返回對應的值,不能用動態規劃的公式做
	if(length<2)
		return 0;
	if(length==2)
		return 1;
	if(length==3)
		return 2;
	//建立陣列儲存子問題最優解
	int* products=new int[length+1];//?
	//繩子大於3米,可以用動態規劃的公式做,f(n)=f(i)*f(n-i)
	//對於繩子長度為1,2,3米的,繩子的最大乘積就是長度本身
	products[0]=0;
	products[1]=1;
	products[2]=2;
	products[3]=3;

	int max=0;
	//從4米開始計算,直到計算到總長
	for(int i=4;i<=length;++i)
	{
		max=0;
		//對於長度為i的繩子,計算所有可能的切分,找到最大值
		for(int j=1;j<=i/2;++j)
		{
			//切分組合
			int product=products[j]*products[i-j];
			if(max<product)
				max=product;

			products[i]=max;
		}
	}
	max=products[length];
	delete[] products;

	return max;
}

三、貪心演算法:

在每一步求解的步驟中,他要求每一步都是最優選擇操作,並且通過一系列的最優選擇,能夠產生一個問題的(全域性的)最優解

3.1 貪心演算法滿足的條件

1、可行的:即它必須滿足問題的約束
2、區域性最優:他是當前步驟中所有可行選擇中最佳的區域性選擇
3、不可取消:即選擇一旦選出,在演算法的後面步驟就不可更改了

3.2 用貪心演算法分析問題

如果我們按照如下的策略來剪繩子,則得到的各段繩子的長度的乘積將最大:當n≥5時,我們儘可能多的剪長度為3的繩子:當剩下的繩子長度為4時,把繩子剪成兩段長度為2的繩子。

3.3程式碼實現:

int maxProductAfterCutting_Solution2(int length)
{
	if(length<2)
		return 0;
	if(length==2)
		return 1;
	if(length==3)
		return 2;

	//儘可能的減去長度為3的繩子段
	int timesOf3=length/3;
	//當繩子最後剩下的長度為4的時候,不能再減去長度為3的繩子段
	//此時更好的方法是把繩子剪成長度為2的兩段,因為2*2>3*1
	if(length-timesOf3*3==1)
		timesOf3-=1;
	
	//最後小於等於4米的,儘量多的產生2米的分割
	int timesOf2=(length-timesOf3*3)/2;

	//3的多少個三次冪乘以2的多少個2次冪
	return (int)(pow(3.0,timesOf3))*(int)(pow(2.0,timesOf2));
}

四、測試及結果

4.1 測試程式碼

int main()
{
	printf("%d\n",maxProductAfterCutting_Solution(10));
	printf("%d\n",maxProductAfterCutting_Solution2(10));
	return 0;
}

4.2 測試結果

在這裡插入圖片描述