動態規劃 堆沙子問題

2021-09-29 17:48:45 字數 1557 閱讀 7632

設有n堆沙子排成一排,其編號為1,2,3,…,n(n≤100)。每堆沙子有一定的數量,如下表

13 7 8 16 21 4 18

現在要將n堆沙子歸併成一堆。歸併的過程為每次只能將相鄰的兩堆沙子堆成一堆,這樣經過n-1次歸併之後最後成為一堆,如上面7堆沙子,可以有多種方法歸併成一堆,歸併的代價是這樣定義的,將兩堆沙子歸併為一堆時,兩堆沙子數量的和稱為歸併2堆沙子的代價。由此可見,不同歸併過程得到的總的歸併代價是不一樣的。

問題:n堆沙子的數量給出之後,找出一種合理的歸併方法,使總的歸併代價為最小。

堆沙子問題只能是相鄰的兩堆沙子,因為這個條件,讓堆沙子的過程有規律可循,問題就可以轉化為如果得到兩堆沙子的過程,依次往下,用f(n,m)來表示最初沙子從第n到第m合併後的值,g(n,m)表示從第n堆到第m堆的總和。我們做個簡單的推演。

f(1,2)=13+7=20   f(2,3)=7+8=15

f(1,3)=f(1,2)+28=f(1,2)+g(1,3)=48

f(1,3)=f(2,3)+28=f(2,3)+g(1,3)=43

當三個合併成乙個的時候就有了兩種選擇,先合併1,2然後3,先合併2,3然後再合併1。

f(1,4)=f(1,2)+f(3,4)+g(1,4)

f(1,4)=f(1,3)+g(1,4)

f(1,4)=f(2,4)+g(1,4)

f(n,m)是由兩部分組成,一部分是兩個沙堆的代價和,另一部分就是g(n,m),g(n,m)在具體的的n,m下就是定值,如果想讓總代價最小,就需要兩個沙堆的代價和最小。

合併情況其實也是可以找到規律的

f(n,m)=f(n,m-1)+g(n,m)

f(n,m)=f(n+1,m)+g(n,m)

f(n,m)=f(n,n+x)+f(n+x+1,m)+g(n,m)

其實合併只有這兩種情況,合併好的加沒有合併過的,兩個合併過的相加。假如f(n,m)=f(n,n+x)+f(n+x+1,m)+g(n,m) 是f(n,m)的最小值,那麼我們只要保證f(n,n+x),f(n+x+1,m)都是最小值就可以。然後依次往下找組成的最小值。但是想找最小值就必須從底層開始計算,一層一層的計算。因為不知道高層的最小情況,所以必須保證從高層計算的所有結果。但是比所有結果都算出來找最小,這種演算法計算的量還是比較小的。他需要從頂向下分析,從下向上計算。

能用動態規劃的情況一般都是頂層結果依賴底層結果,他們直接的是一種包含關係,但是分治法分開的小組計算的結果沒有任何影響。這也是兩種演算法的區別。

public static void sand() ;

//用乙個二維陣列來儲存中間需要的結果

int sumdata = new int[weight.length][weight.length];

//len用來控制層數計算

int len = 1;

while (len < weight.length-1)

sumdata[i][j] = min + sum(weight, i, j);

}len++;

} system.out.println(sumdata[1][weight.length-1]);

}

動態規劃,西瓜分堆問題

lijingjing 將西瓜分成兩份,求其最小差值,其極致情況為兩組資料相等,差值最小為0 當不是極值狀態時,其最小差值的兩組一定是最接近總和的一半的兩個數 所以,同01揹包問題。q求組成總和一半數的最大情況 includeusing namespace std int n,a 14 int b 1...

中等 動態規劃經典 堆石子問題

1.問題描述 設有n堆沙子排成一排,其編號為1,2,3,n n 100 每堆沙子有一定的數量。現要將n堆沙子並成為一堆。歸併的過程只能每次將相鄰的兩堆沙子堆成一堆,這樣經過n 1次歸併後成為一堆。找出一種合理的歸併方法,使總的代價最小。輸入格式 輸入由若干行組成,第一行有乙個整數,n 1 n 100...

動態規劃問題

思想 如果乙個問題是由交疊的子問題所構成,那麼我們就可以用動態規劃技術來解決它。一般來說,這樣的子問題出現在對給定問題求解的遞迴關係中。這個遞推關係包含了相 同問題的更小子問題的解。動態規劃法建議,與其對交疊子問題一次又一次的求解,不如把每個較小子問題只求解一次並把結果記錄在表中。例題 0 1揹包問...