区间DP

Posted 125418a

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了区间DP相关的知识,希望对你有一定的参考价值。

内容参考书籍《算法竞赛入门到进阶》

区间DP就是先在小区间进行DP,然后合并小区间,得到大区间,直到解决最后的大区间问题。相较于普通的DP问题,它不仅需要状态转移方程还需要枚举所有可能的区间。

通常情况下,区间DP至少需要两层for循环,例如:

	for (int i = 1; i < n; ++i)
	{
		for (int j = i; j <= n; ++j)
		{
			...
		}
	}

  下面引入两个经典问题:

1.石子合并:有n堆石子排成一排,每堆石子有一定的数量,将这n堆石子合成一堆,每次只能合并相邻的两堆,合并花费为两堆石子总数,求最小花费。

输入:

3
2 4 5

输出:

17

计算过程为:一:2+4=6,二:6+5=11,三:6+11=17,故答案为17。

设dp[i][j]为从第i堆石子到第j堆石子的最小花费,那么答案为dp[1][n]。另外,设sum[i][j]为从第i到j的区间和。

那么合并两堆,例如dp[1][2],是指合并1-2,就有dp[1][2] = dp[1][1] + dp[2][2] + sum[1][2],也即是dp[i][i+1] = dp[i][i] + dp[i+1][i+1] + sum[i][i+1]

合并三堆,例如dp[1][3],则有两种情况,先合并1-2再3,或者先2-3再1,即dp[1][3] = min(dp[1][1] +dp[2][3], dp[1][2] + dp[3][3])+sum[1][3]。

也即是dp[i][i+2] = min(dp[i][i]+dp[i+1][i+2] , dp[i][i+1] + dp[i+2][i+2])+sum[i][i+2]。

推广:dp[i][j] = min(dp[i][k]+dp[k+1][j])+sum[i][j-i+1]。

代码如下:

(后续代码明天写)

以上是关于区间DP的主要内容,如果未能解决你的问题,请参考以下文章

HDU 5115 Dire Wolf ——(区间DP)

HDU 5115 Dire Wolf(区间dp)

区间DP小结(附经典例题) 转载

poj2955 区间dp

BZOJ1260 [CQOI2007]涂色paint(区间dp)

括号匹配问题(区间dp)