p1880 石子合併

2021-08-09 21:32:39 字數 2082 閱讀 1467

先從線性的開始吧。

有n堆石子排成一排,每堆石子有一定的數量。現要將n堆石子並成為一堆。合併的過程只能每次將相鄰的兩堆石子堆成一堆,每次合併花費的代價為這兩堆石子的和,經過n-1次合併後成為一堆。求出總的代價最小值。

樣例:

[輸入]

3 1 2 3

7 13 7 8 16 21 4 18

[輸出]

9 239

由於是相鄰兩個進行合併,貪心演算法並不是最優的演算法(比如第二組)。

可以用區間dp來解決。

狀態:設f[i][j]表示從第i堆到第j堆得石子中所需的最小代價

決策:在區間[i,j)中列舉乙個k,則f[i][j] = min(f[i][k] + f[k+1][j] + s[i][j]);

其中s[i][j]表示這段區間的石子數。

用i列舉上界,用l來列舉區間長度,那麼j = i + l;

k來列舉區間中選定的那一堆。

時間複雜度為o(n^3)

#include

#include

#include

#include

#include

#define n 50

#define inf 100000

using

namespace

std;

inline

int read()

int sum[n+1];

int f[n][n];

int main()

memset(f,0,sizeof(f));

for (int l=2;l<=n;l++)

}cout

<1][n];

}

如果對於任意的a1≤a2 < b1≤b2,

有m[a1,b1]+m[a2,b2]≤m[a1,b2]+m[a2,b1],那麼m[i,j]滿足四邊形不等式。

設m[i,j]表示動態規劃的狀態量。

m[i,j]有類似如下的狀態轉移方程:

m[i,j]=min(i≤k≤j)

m滿足四邊形不等式是適用這種優化方法的必要條件

對於一道具體的題目,我們首先要證明它滿足這個條件,一般來說用數學歸納法證明,根據題目的不同而不同。

通常的動態規劃的複雜度是o(n^3),我們可以優化到o(n^2)

定義s(i,j)為函式m(i,j)對應的使得m(i,j)取得最小值的k值。

我們可以證明,s[i,j-1]≤s[i,j]≤s[i+1,j]

那麼改變狀態轉移方程為:

m[i,j]=min(s[i,j-1]≤k≤s[i+1,j])

複雜度分析:不難看出,複雜度決定於s的值,以求m[i,i+l]為例,

(s[2,l+1]-s[1,l])+(s[3,l+2]-s[2,l+1])…+(s[n-l+1,n]-s[n-l,n-1])=s[n-l+1,n]-s[1,l]≤n

所以總複雜度是o(n)

以上所給出的狀態轉移方程只是一種比較一般的,其實,很多狀態轉移方程都滿足四邊形不等式優化的條件。

解決這類問題的大概步驟是:

證明w滿足四邊形不等式,這裡w是m的附屬量,形如m[i,j]=opt,此時大多要先證明w滿足條件才能進一步證明m滿足條件

證明m滿足四邊形不等式

證明s[i,j-1]≤s[i,j]≤s[i+1,j]

w[a,c]+w[b,d]<=w[b,c]+wa,d 就稱其滿足凸四邊形不等式

或打表觀察w[i][j+1]-w[i][j]關於i的表示式,如果關於i遞減,則w滿足凸四邊形不等式

如果乙個函式w[i][j],滿足 w[i』][j]<=w[i][j』] i<=i』<=j<=j』 則稱w關於區間包含關係單調

如果w同時滿足四邊形不等式和區間單調關係,則dp也滿足四邊形不等式

如果石子是環形排列的,由於k是我們列舉的,可以保證在1到n裡,但是k+1和j可能會超出範圍。因此f[i][j] = min(f[i][k]+f[(i+k+1)%n][j-k-1]+sum[i][i+j]),其中對於sum[i][i+j]

參考:

P1880 石子合併

石子歸併最簡單的情況是一排石子,典型的區間dp問題。dp i j 的含義是區間 i,j 合併之後的最大或最小花費 轉移方程 dp i j max min dp i j dp i k dp k 1 j val i,j 對於區間 i,j 它可以由區間 i,k 和區間 k 1,j 合併而來,合併時,要加上...

P1880石子合併

傳送 這是乙個年代久遠的區間dp 好像以前培訓的時候講了,但是現在才想起來去a 區間dp常用狀態 f i j 以i為左端點,j為右端點的最優解 第一層迴圈列舉區間長度,第二層迴圈列舉起點,第三層列舉中間的斷點 貌似寫到這裡這個題就寫完了 特點 問題能轉換為兩兩合併的問題 such as 能量項鍊,石...

洛谷P1880 石子合併

描述 在乙個園形操場的四周擺放n堆石子,現要將石子有次序地合併成一堆.規定每次只能選相鄰的2堆合併成新的一堆,並將新的一堆的石子數,記為該次合併的得分。試設計出1個演算法,計算出將n堆石子合併成1堆的最小得分和最大得分.輸入格式 資料的第1行試正整數n,1 n 100,表示有n堆石子.第2行有n個數...