鋼條切割問題

2021-09-25 14:17:00 字數 2484 閱讀 9354

一、

問題描述

給定乙個長度為n英吋的鋼條和一張**表(英吋/美元),求乙個切割方案使得獲取的收益r最大。

例如,對於如下的**表:

給定長度n為4英吋,則獲取的最大利益為10美元,對應的切割方案為:2+2。

一種遞迴求解法

在不考慮切割順序的前提下(1+(n-1)和(n-1)+1這兩種切割方式實際上收益是一樣的,可視為一種切割方案),長度為n的鋼條共有2^(n-1)種切割方案。

可以考慮,

當被切割的子段中其中有一條為長度1的情況下,最大收益為r1;

當被切割的子段中其中有一條為長度2的情況下,最大收益為r2;

當被切割的子段中其中有一條為長度n(不做任何切割)的情況下,最大收益為rn;

不難發現,最大收益rmax = max(r1,r2..rn);

演算法實現:

public

static

int getmaxreturn(int price,int

n)

int profit = 0;

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

return

profit;

}

該演算法的實際是比較低效的,因為其遞迴樹中求解了很多重複的子問題,未能成分利用第一次對相同子問題求解的結果。

其遞迴時間複雜度的遞推公式為:

其中t(0)為遞迴基的呼叫,t(0)=1;

用錯位相減:t(n)-t(n-1)可以將其化簡為更加明顯的遞推式:

其結論已經十分明顯,顯然t(n)=2^n,因此該遞迴版本的演算法是乙個指數時間複雜度的演算法,起根本原因在於:遞迴樹中重複計算了很多相同子問題。子問題的規模越小,重複計算的次數就越多。

動態規劃求解

分析:從以上低效的遞迴演算法版本優化到動態規劃演算法實現實際上是很自然而然的思路,既然子問題被重複計算是導致以上演算法的低效的原因,那麼如果能夠利用對子問題求解的結果,就能避免對子問題的重複計算,優化其時間複雜度,因此會利用額外的空間儲存已求得的子問題的解。

以時間換空間是動規劃問題的基本特徵,是典型的時空權衡的策略。

動態規劃版本實現:

public

static

int getmaxreturn(int price,int

n) aux[i] =tmpr;

}return

aux[n];

}

整個過程輔助陣列記錄了各個子問題的最大收益:

0,1,5,8,10,13,17,18,22,25,30
二、另外一種思考方案:求解子問題長度為i的鋼條時,由於i本身可以不切割算作乙個整體,那麼這裡就存在乙個0-1決策的問題:如果不切割,價值為p[i];如果切割,假設在j處被切割,原問題被分成規模更小的兩個子問題,前半部分的長度為j,後半部分的長度為i-j,而這兩個子問題已然已經在之前求解。組合這兩個子問題的最優解可以得到原問題的最優解。

切割點j是不定的,實際上由於切割的對稱關係,j只需要遍歷前半部分即可。

其遞推式表示為:

這樣思考可能不上面的動態規劃在時間複雜度上爭取到更小的常係數。

演算法實現:

/*

* 動態規劃版本實現,另一種實現方式

* */public

static

int getmaxreturn(int price,int

n) }

return

aux[n];

}

三、問題的公升級:給定乙個長度為n(n>=2)英吋的鋼條和一張**表(英吋/美元),但是有乙個限制條件:要求至少被切割一次。求乙個切割方案使得獲取的收益r最大。

這個問題實際上稍微不同於前面的問題,從原問題角度看必須被切割,但是其子問題可以不被切割。

因此,好的解決方案是:

要求解規模為n的原問題,先求解規模為n-1的子問題,但是求解規模為n-1的子問題是,不用管限制條件,在最有依次求解n的時候,再加上限制條件即可。

演算法實現:

/*

* 如果鋼條必須要求切割至少依次

* */public

static

int getmaxreturn(int price,int

n) }

int maxr = 0;

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

return

maxr;

}

鋼條切割問題

動態規劃的一般步驟 1.刻畫乙個最優解的結構特徵 2.遞迴定義最優解的值 3.計算最優解的值,通常採用自底向上的方法 4.利用計算出的資訊構造乙個最優解 利用動態規劃方法求解類似鋼條切割方案的這一類遞迴問題,可避免反覆求解相同的子結構,下面是樸素遞迴演算法和用動態規劃設計的遞迴演算法的相應實現。鋼條...

鋼條切割問題

class program 索引代表 鋼條的長度,值代表 console.writeline updown 0 p console.writeline updown 1 p console.writeline updown 2 p console.writeline updown 3 p conso...

鋼條切割問題

對應於演算法導論上的鋼條切割問題。package dynamic programming 動態優化問題之鋼條切割問題 長度i 1 2 3 4 5 6 7 8 9 10 p 1 5 8 9 10 17 17 20 24 30 問題,對於長度為i的鋼條,怎麼切割,使之價值最大。public class ...