區間dp小結

2021-06-21 16:13:57 字數 1881 閱讀 2655

區間dp,顧名思義,就是在區間上dp,即把整個區間劃分為乙個個的小區間,在小區間內dp求出最優值,然後把這些小區間合併以後就是整個取件的最優值。

下面是一些比較經典的區間dp題目:

1.nyoj 737 石子合併:

題意:有n堆石子,每堆有a[i]個,每次合併時只能合併相鄰的兩堆,代價為兩堆石子的個數之和。問把這n堆石子合併成一堆需要的最小代價是多少。

狀態:dp[i][j] 表示合併第 i 堆到第 j 堆石子的最小代價

轉移方程;dp[i][j] = min(dp[i][j], dp[i][k] + dp[k+1][j] + sum[j] - sum[i-1]);

其中sum[i]表示前i堆石子的總個數。

#include#include#includeusing namespace std;

#define inf 0x3fffffff

const int n = 205;

int a[n], sum[n], dp[n][n];

int main()

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

}printf("%d\n",dp[1][n]);

}return 0;

}

2.poj 2955 brackets 

題意:給出一串由『(『,』)『,』[',『]』組成的字串,問最多有多少個括號匹配。

狀態:dp[i][j]表示 i 到 j 最多的匹配個數

轉移方程:dp[i][j] = max(dp[i][j], dp[i][k] + dp[k+1][j]);

#include#include#includeusing namespace std;

const int n = 105;

char str[n];

int dp[n][n];

bool judge(char a, char b)

int main()

for(int k = 2; k < len; k++) //列舉子串的長度

}printf("%d\n",dp[0][len-1]);

}return 0;

}

3.poj 1141 brackets sequence

題意:給出一串由『(『,』)『,』[',『]』組成的字串,求使原串裡面的括號全部匹配後的長度最短的字串。

狀態:dp[i][j] 表示使 i 到 j 全部匹配最少需要新增的括號個數。

轉移方程:dp[i][j] = min(dp[i][j], dp[i][k] + dp[i+1][k]);

#include#include#define inf 0x3ffffff

const int n = 105;

char str[n];

int dp[n][n], flag[n][n];

bool judge(char a, char b)

void print(int i, int j)

else if(flag[i][j] == -1)

else

}int main()

for(int k = l; k < r; k++)

if(dp[l][r] > dp[l][k] + dp[k+1][r])

dp[l][r] = dp[l][k] + dp[k+1][r], flag[l][r] = k; //flag[l][r]=k表示以k為分割點的兩端的匹配之和最優}}

//printf("%d\n",dp[0][len-1]);

print(0, len-1);

printf("\n");

}return 0;

}

線性dp 區間dp

1 尼克的任務 額一道挺水的題,愣是做了幾個小時 動態規劃大致的思路還是找乙個轉移 換個詞就是影響 我們可以明顯看出本題的規則 空暇時,一遇到任務必須挑乙個接 求1 n時間內最大空暇時間 所以將任務排序是必要的,兩個關鍵字 再來想象一下當我做到第i 個任務時,我在 st i st i t i 1 時...

線狀DP及區間DP

這裡我們都用到動態規劃的思想 dynamic programming,簡稱dp。本質就是組合子問題來求解原問題,且對每個子問題只求解一次。一般來說四個步驟 1.刻畫乙個最優結構特徵 2.遞迴的定義最優解值 3.計算最優解的值 4.利用計算出的資訊構造乙個最優解 這邊直接給出 include incl...

區間DP結構

區間動態規劃問題一般都是考慮,對於每段區間,他們的最優值都是由幾段更小區間的最優值得到,是分治思想的一種應用,將乙個區間問題不斷劃分為更小的區間直至乙個元素組成的區間,列舉他們的組合 求合併後的最優值。設f i,j 1 i j n 表示區間 i,j 內的數字相加的最小代價 最小區間f i,i 0 乙...