区间dp学习笔记

区间dp学习笔记

具体思路

区间dp,故名思意,就是在一段区间里做动态规划操作,一般的区间dp都运用了如下操作

  1. 状态表示:dpi,j 一般表示的是 ij 这一段区间里面的答案 ,答案为 dp1,n
  2. 边界处理:dpi,i 只表示一个数字,我们直接按照题意初始化
  3. 三层循环,遍历区间长度 len ,左节点 l ,易得右节点 rlen+i1 ,中间一些判断语句,最后一层循环在区间内寻找断点 k

一般的状态转移方程为

dpi,j=max(dpi,j,dpi,k+dpk+1,j+......)

至于你前面的 max 还是 min,我们根据题意来判断,注意我们处理的区间还可以是环状的,这时后我们就要来处理一下边界,并将数组开大,再处理一下即可。

综上所述,一般的区间dp时间复杂度为 O(n3) ,空间复杂度为 O(n2)

习题

1.P1775 石子合并(弱化版)

我们设 fi,jij 的区间内的最小代价,再用前缀和优化

边界条件:fi,i=0

状态转移方程

fl,r=min(fl,r,fl,k+fk+1,r+srsl1);

s 数组为前缀和数组,答案为 f1,n

2.P4170 [CQOI2007]涂色

我们设 dpi,jij 的区间内的最小涂色次数

边界条件:dpi,i=1

状态转移方程分成两种情况

1.strl=strr 的时候

可以想到只需要在首次涂色时多涂一格即可,状态转移方程:dpl,r=min(dpi+1,j,dpi,j1)

2.否则枚举断点:

dpl,r=min(dpl,r,dpl,k+dpk+1,r);

for (int x = 1; x < n; x ++ ) { for (int l = 1, r = x + 1; r <= n; l ++ , r ++ ) { if(s[l] == s[r]) dp[l][r] = min(dp[l + 1][r], dp[l][r - 1]); else for (int k = l; k < r; k ++ ) dp[l][r] = min(dp[l][r], dp[l][k] + dp[k + 1][r]); } }

3.P1063 [NOIP2006 提高组] 能量项链
dpi,jij 的区间内的最大能量

边界条件:dpi,i+1=0

n 个珠子合并弄成 n+1 个"石头"合并

状态转移方程:dpl,r=max(dpl,r,dpl,k+dpk,r+alakar);

典型的环形区间dp

for (int len = 2; len <= n + 1; len ++ ) { for(int l = 1, r; l + len - 1 <= n << 1; l ++ ) { r = l + len - 1; if(len == 2) dp[l][r] = 0; else { for(int k = l + 1; k < r; k ++ ) dp[l][r] = max(dp[l][r], dp[l][k] + dp[k][r] + a[l] * a[k] * a[r]); } } }

__EOF__

本文作者ljfyyds
本文链接https://www.cnblogs.com/ljfyyds/p/16537642.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   ljfyyds  阅读(108)  评论(2编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示