Acwing 282 石子合併 區間dp

2022-07-18 04:42:13 字數 1618 閱讀 7270

區間dp問題,其基本思路就是

對於每段區間,他們的最優值都是由幾段更小區間的最優值得到,是分治思想的一種應用,將乙個區間問題不斷劃分為更小的區間直至乙個元素組成的區間,列舉他們的組合 ,求合併後的最優值。

設f[i,j](1<=i<=j<=n)表示區間[i,j]內的數字相加的最小代價

最小區間f[i,i]=0(乙個數字無法合併,∴代價為0)

每次用變數k(i<=k<=j-1)將區間分為[i,k]和[k+1,j]兩段。

for len=1 to n do // len是區間長度,作為階段。 

for i=1 to n do // i是窮舉的區間的起點

begin

j=i+len-1; // j是 區間的終點,這樣所有的區間就窮舉完畢

if j>n then break; // 這個if很關鍵。

for k:= i to j-1 do // 狀態轉移,去推出 f[ i , j ]

f[ i , j ]= max 

end; 

這個結構必須記好,這是區間動態規劃的**結構。

設有n堆石子排成一排,其編號為1,2,3,…,n。

每堆石子有一定的質量,可以用乙個整數來描述,現在要將這n堆石子合併成為一堆。

每次只能合併相鄰的兩堆,合併的代價為這兩堆石子的質量之和,合併後與這兩堆石子相鄰的石子將和新堆相鄰,合併時由於選擇的順序不同,合併的總代價也不相同。

例如有4堆石子分別為 1 3 5 2, 我們可以先合併1、2堆,代價為4,得到4 5 2, 又合併 1,2堆,代價為9,得到9 2 ,再合併得到11,總代價為4+9+11=24;

如果第二步是先合併2,3堆,則代價為7,得到4 7,最後一次合併代價為11,總代價為4+7+11=22。

問題是:找出一種合理的方法,使總的代價最小,輸出最小代價。

輸入格式

第一行乙個數n表示石子的堆數n。

第二行n個數,表示每堆石子的質量(均不超過1000)。

輸出格式

輸出乙個整數,表示最小代價。

資料範圍1≤

n≤300'>1≤n≤3001≤n≤300

輸入樣例:

4

1 3 5 2

輸出樣例:

22

對於這兒道題就是dp[ i ][ j ]表示從第i堆石子到第j堆石子的集合,而其屬性就是合併相鄰兩堆石子花費的最小值。

其狀態轉移方程為dp[ i ][ j ]=min(dp[ i ][ j ],dp[ i ][ k ]+dp[ k+1 ][ r ]+s[ r ]-s[ l-1 ])。

1 #include2 #include3 #include4

5using

namespace

std;67

const

int n=330;8

ints[n];

9int

n;10

intdp[n][n];

1112

intmain()

1323

24for(int len=2;len<=n;len++)

2532}33

34 cout<1][n]<3536

return0;

37 }

ACWing 282 石子合併

n nn堆石子排成一排,編號為1 n 1 sim n 1 n。每堆石子的個數由乙個非負整數陣列a aa描述。現在要將這些石子合併為1 11堆,每次可以合併兩堆石子,所消耗的能量是這兩堆石子的總數。問合併為1 11堆為止所消耗的能量的最小值。輸入格式 第一行乙個數n nn表示石子的堆數n nn。第二行...

acwing 282 石子合併(區間dp)

設有n堆石子排成一排,其編號為1,2,3,n。每堆石子有一定的質量,可以用乙個整數來描述,現在要將這n堆石子合併成為一堆。每次只能合併相鄰的兩堆,合併的代價為這兩堆石子的質量之和,合併後與這兩堆石子相鄰的石子將和新堆相鄰,合併時由於選擇的順序不同,合併的總代價也不相同。例如有4堆石子分別為 1 3 ...

ACwing 282 石子合併(區間dp

給出n堆石子,每次只能合併相鄰的兩堆石子,代價為兩堆石子的質量和,求合併所有石子的最小代價。區間dp中i,j表示的是兩個區間的左右端點,操作物件是區間。dp i j 表示合併第i堆石子到第j堆石子的最小代價。對於i,j圍成的區間,以合併的分割線區分不同合併方式,相當於在i,j中插入一塊隔板,dp i...