码迷,mamicode.com
首页 > 其他好文 > 详细

区间DP

时间:2020-05-25 23:44:35      阅读:104      评论:0      收藏:0      [点我收藏+]

标签:最小   经典   计算   区间问题   循环   问题:   过程   就是   两种   

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

区间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

标签:最小   经典   计算   区间问题   循环   问题:   过程   就是   两种   

原文地址:https://www.cnblogs.com/125418a/p/12952824.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!