区间DP入门

区间DP是解决从一点到另一点的连续区间内的最优值或计数问题,通过两维数组表示区间起始和结束。它从小区间扩展到大区间,以O(n^3)的时间复杂度计算。对于环形区间DP,可以通过将序列自身拼接形成新的区间,然后用类似的方法处理。在处理环形区间时,需控制区间长度不超过原长度,并更新对应位置的最优解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

普通区间DP

从某个点到另一个点的连续区间求最优值或计数问题,称为区间DP。

区间DP通常需要使用两维分别表示区间的起始位置与结束位置。

f[i][j] 即表示从 ij 的最优值。

显然,区间DP是从小区间推到大区间,大区间的解是由小区间构成的。

(1)需要控制区间从小到大

模板:先枚举右端点 j j j,再从 j j j 左边继续向左枚举左端点 i i i,把区间一点点拉大。

for (int j = 1; j <= n; ++j)
	for (int i = j-1; i; --i)

这样可以保证,每次要求的区间 f[i][j],它的任意一个子区间都是已经求过最优解的。

(2)我们只需要将区间分为两个子区间,将其合并即可,两个子区间各自也是之前由它们各自的子区间合并而来的。

for (int j = 1; j <= n; ++j)
	for (int i = j-1; i; --i)
		for (int k = i; k <= j; ++k)
			f[i][j] = min(f[i][j], f[i][k]+f[k][j]);

所以区间DP的时间复杂度通常是 O ( n 3 ) O(n^3) O(n3)

环形区间DP

还有一类情况的区间DP,整个数列首位相接构成一个环形。

对于这类题目,不论是区间DP,还是以前做过的 字符串移位包含问题,思路都是一样的,即将字符串在末尾再拼接一遍,然后转换为普通的区间DP问题。注意:序列长度仍须维持为原长度,因此需要两个维来控制区间大小,用 f[i][j] 表示区间 [i,j] 的最优解。
对于一个长度为 n n n 的区间,它的起始位置可能有 n ( 1 ∼ n ) n(1\sim n) n(1n) 种,对应的结束位置也有 n ( n ∼ 2 n − 1 ) n(n\sim 2n-1) n(n2n1) 种。
通常需要更新 f[i][i]

for (int j = 1; j < (n<<1); ++j)
	for (int i = j-1; i > j-n; --i)//控制区间长度不能超过n
		for (int k = i; k <= j; ++k)
			f[i][j] = min(f[i][j], f[i][k]+f[k][j]);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值