nyoj737 石子歸併 區間dp入門題

2022-05-01 23:09:16 字數 1108 閱讀 7065

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

解題關鍵:區間dp,首先列舉區間,再列舉分割點,區間由小到大更新。

轉移方程:$dp[l][r] = \min (dp[l][r],dp[l][i + 1] + dp[i + 1][r] + w[i][j])$

複雜度:$o()$

注意$dp[i][i] = 0$

**的比較好的一段理解:

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

設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 l:=1 to n do // l是區間長度,作為階段。 

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

begin

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

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

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

f[i , j]= max 

end; 

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

1 #include2

using

namespace

std;

3 typedef long

long

ll;4

const

int maxn=302;5

inta[maxn],sum[maxn];

6int

dp[maxn][maxn];

7int

main()18}

19 cout<1][n]<<"\n"

;20}21 }

nyoj737 石子合併 區間dp

描述 有n堆石子排成一排,每堆石子有一定的數量。現要將n堆石子並成為一堆。合併的過程只能每次將相鄰的兩堆石子堆成一堆,每次合併花費的代價為這兩堆石子的和,經過n 1次合併後成為一堆。求出總的代價最小值。輸入 有多組測試資料,輸入到檔案結束。每組測試資料第一行有乙個整數n,表示有n堆石子。接下來的一行...

NYOJ 737 石子歸併問題 (區間DP1)

題意 中文題目 解題方法 基礎區間dp。要求n個石子歸併,我們根據dp的思想劃分成子問題,先求出每兩個合併的最小代價,然後每三個的最小代價,依次知道n個。定義狀態dp i j 為從第i個石子到第j個石子的合併最小代價。則有 dp i j m in d p i k dp k 1 j 那麼我們就可以從小...

nyoj 737 石子合併 經典區間 dp

時間限制 1000 ms 記憶體限制 65535 kb 難度 3 描述 有n堆石子排成一排,每堆石子有一定的數量。現要將n堆石子並成為一堆。合併的過程只能每次將相鄰的兩堆石子堆成一堆,每次合併花費的代價為這兩堆石子的和,經過n 1次合併後成為一堆。求出總的代價最小值。輸入 有多組測試資料,輸入到檔案...