区间dp, 属于dp的一种,顾名思义,便是对区间处理的dp,其中石子归并,括号匹配,整数划分最为典型。
(1)石子归并
dp三要素:阶段,状态,决策。
首先我们从第i堆石子到第j堆石子合并所花费的最小费用设为dp[i][j], 然后去想状态转移方程,dp[i][j]必然有两堆石子合并而来, 那么我们很快就可以推出状态转移方程为dp[i][j] = min(dp[i][j], dp[i][k] + dp[k+1][j] + s);(s为两堆石子的总和)
下面附上代码
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 const int N = 200 + 5; 6 int a[N], dp[N][N], n, sum[N]; 7 8 void work(){ 9 for(int l = 1; l <= n; l ++){ 10 for(int i = 1; i + l <= n; i ++){ 11 int j = i + l; 12 for(int k = i; k <= j; k ++){ 13 dp[i][j] = min(dp[i][j], dp[i][k] + dp[k+1][j] + sum[j] - sum[i-1]); 14 } 15 } 16 } 17 printf("%d\n", dp[1][n]); 18 } 19 20 int main(){ 21 while(scanf("%d", &n) == 1){ 22 memset(dp, 0x3f,sizeof(dp)); 23 for(int i = 1; i <= n; i ++){ 24 scanf("%d", a + i); 25 sum[i] = sum[i-1] + a[i]; 26 dp[i][i] = 0; 27 } 28 work(); 29 } 30 return 0; 31 }