所謂區間dp,顧名思義就是在一段區間上的動態規劃。它既要滿足dp問題的最優子結構和無後效性外,還應該符合在區間上操作的特點。我的理解是往往會對區間進行合併操作。抑或是單個元素(可看成乙個小區間)跨區間進行操作。例如括號匹配問題,石子合併問題(通過多次的相鄰合併,最後實質上會產生跨區間的合併,如果你把其中的石子看作參考係的話就很容易感覺出來),還有在整數中插入運算符號的問題(利用運算子的優先順序以及交換律可看出)
這樣以來,如果我們要得知乙個大區間的情況,由於它必定是由從多個長度不一的小區間轉移而來**移情況未知),我們可以通過求得多個小區間的情況,從而合併資訊,得到大區間。
對於乙個長度為n的區間,確定它的子區間需要首尾兩個指標,顯然子區間數量級為n2,那區間dp的複雜度也就為n2
for (int len = 1; len < n; len++)
}}
石子並歸問題
很多個石子合併成一堆,
最後一定會進行到還有兩堆石子
然後把他們合併成一堆(這一步的花費是這一堆石子的總大小),再乙個,最後這兩堆石子一定(1~k)個和(k+1~n)的石子合併而來,所以我們就有了乙個最後一步的公式:
dp[1][n] = min(dp[1][n] , dp[1][k] + dp[k+1][n] + sum[1][n])
然後,我們再看,dp[1][k]和dp[k+1][n]是不是也是通過上面的那個公式算出來的,而且要使得dp[1][n]最小那麼,dp[1][k]和dp[k+1][n]一定也是如此算出來的最小值(也就是經過合併成這一堆的最小花費)
因此,我們要算出個大區間的石子合成最小值,是不是就要算出某兩個小區間的最小值,如此下去,我們是不是就需要從區間長度的從小到大這樣dp下去(因為我們只知道長度為1的區間值啊),最後算出這個dp[1][n]的最小值,所以我們就有了下面的**:(有的同學可能有疑問,為什麼要算出中間一些區間的dp呢,你看哈,我們的dp[1][k]是不是由某個dp[1][s]和dp[s+1][k]算出來的,那麼我們這個dp[s+1][k]是不是就是中間的某個區間了)
#include#include#include#include#define n 210
const int inf = 1e9;
using namespace std;
int dp[n][n];
int sum[n];
int a[n];
int main()
for (int len = 1; len < n; len++) }}
printf("%d\n", dp[1][n]);
}return 0;
}
括號匹配問題
好了,接下來我們來看看另乙個經典的區間dp問題,括號匹配問題,這裡我們就不講題目的大意了,直接來講題目的思路吧
我們要求出乙個區間最大的括號匹配長度,同樣,這個區間一定可以分成兩個區間,但是,這裡的分法就有了兩種哦,沒錯,就是模板中檢查是否匹配的那種啦!我們來舉乙個例子:(()(())),我們來拆這個字串,因為是匹配問題,我們是不是有兩種拆法,一種是類似於上面石子並歸拆成兩個區間,另一種就是最左邊和最右邊的匹配,然後加上中間的,下面就來看**理解下吧!
#include#include#include#include#include#define n 110
const int inf = 1e9;
using namespace std;
char str[n];
int dp[n][n];
bool ck(int i, int j) else
}int main(int argc, const char * argv)
// 討論區間合併情況,求最大值
for (int k = i; k < j; k++) }}
printf("%d\n", dp[0][len - 1]);
}return 0;
}
USACO A Game (經典區間DP)
a game遊戲 ioi 96 day 1 有如下乙個雙人遊戲 n 2 n 100 個正整數的序列放在乙個遊戲平台上,遊戲由玩家1開始,兩人輪流從序列的兩端取數,取數後該數字被去掉並累加到本玩家的得分中,當數取盡時,遊戲結束。以最終得分多者為勝。編乙個執行最優策略的程式,最優策略就是使玩家在與最好的...
經典 區間dp 合併石子
題目鏈結 這個動態規劃的思是,要得出合併n堆石子的最優答案可以從小到大列舉所有石子合併的最優情況,例如要合併5堆石子就可以從,最優的2 3和1 4中得到最佳的答案。從兩堆最優到三堆最優一直到n堆最優。狀態轉移方程式 dp i j min dp i k dp k 1 j 複雜度為o n 3 inclu...
區間DP經典 石子合併
題目鏈結 題意 環形的一群石子,每次可以選擇相鄰的兩堆合併,分數為新得到的一堆石子,求將這片石子合併成一堆的最大和最小分數 輸入 第一行乙個正整數n,其後n個數代表每堆石子的個數 分析 第一次寫的時候我想當然的寫的狀態轉移方程是dpx l r max dpx l 1 r a l r dpx l r ...