区间DP总结

做了几题区间动态规划的题目,觉得区间动态规划的题目是有点难的。区间DP大概是这一类的动态规划,在一个线性的数据上对区间进行状态转移,dp[i][j]表示i到j的区间。dp[i][j]可以由子区间的状态转移而来,关键是dp[i][j]表示的是什么,然后去找dp[i][j]和子区间的关系。要知道,在求dp[i][j]之前,i到j之间的子区间都已经求出来最优解。
一点一点说吧!
首先我觉得首先区间DP的应用要先想到回文串的,包括一个字符串的最长的非连续的回文串,一个字符串非连续的回文串的数目。因为回文串的特点对应的两端字符是相等的,所以状态是可以转移的,先看一道求一个字符串中回文串的数目:
HDU 4632

题解:
http://blog.csdn.net/Dacc123/article/details/50886011

接下来就是求回文串的最长的长度问题
HDU 4745
这道题目是在求区间最长的回文串长度升级一下,序列是一条链。这里可以用倍增的方法。状态转移方程:
dp[i][j]= max ( dp[i+1][j], max ( dp[i][j-1],
( a[i]==a[j] ? dp[i+1][j-1] + 2 : dp[i+1][j-1] ) ) );就是在dp[i+1][j],dp[i][j-1],dp[i+1][j-1]三个子区间求最大值。

题解:
http://blog.csdn.net/dacc123/article/details/50911832

这道题和前面的比较,求最长的长度是在dp[i+1][j],dp[i][j-1],dp[i+1][j-1]三个子区间里进行比较,而求数量,则是把求子区间的和。这两道的题目的子区间只涉及到dp[i+1][j],dp[i][j-1],dp[i+1][j-1],并没有在i到j之间进行区间划分,这是因为回文串的特性。

下面看划分区间的区间DP问题:
题目链接
http://poj.org/problem?id=2955
这是一道简单的区间划分dp题目
求最长的匹配括号的长度,划分区间是没有条件的,从i到j区间内任何一点都可以划分,dp[i][j]=max(dp[i][k]+dp[k+1][j]){k=i….j}
题解:
http://blog.csdn.net/dacc123/article/details/50906703

题目链接
http://poj.org/problem?id=1651
题解:
http://blog.csdn.net/dacc123/article/details/50911318

题目链接
http://lightoj.com/login_main.php?url=volume_showproblem.php?problem=1422
状态转移方程是要在i到j区间之间进行区间划分。你可以从左端点开始,也可以从右端点开始。只有当k等于左端点或者右端点的时候才可以划分。因为这样的话,第k天就不用穿新衣服,少买了一件,这也是得到最优解的关键,
题解:
http://blog.csdn.net/dacc123/article/details/50979300

再看这道题目的升级版
http://acm.hdu.edu.cn/showproblem.php?pid=2476
在前面的基础上,再进行一次区间DP
题解:
http://blog.csdn.net/dacc123/article/details/50799405

再看一道难度增加的区间划分
题目:
http://acm.hdu.edu.cn/showproblem.php?pid=4283
这道题目在划分区间之后,要计算因为状态改变,而改变的不满意值
题解:
http://blog.csdn.net/dacc123/article/details/50902212

有时候区间DP的状态要根据题目有不同的形式,不仅是二维数组表示区间,也可以加其他维,表示不同的状态。
题目链接
http://blog.csdn.net/dacc123/article/details/50911318
这道题目用来四维数组,另外两维表示左边和右边的颜色种类
题解:
http://blog.csdn.net/dacc123/article/details/51002776

题目链接
http://www.icpc.moe/onlinejudge/showProblem.do?problemCode=3469
三维数组,第三维表示快递小哥在区间的哪一边?
题解:
http://blog.csdn.net/dacc123/article/details/51002803

最优三角划分:
http://www.icpc.moe/onlinejudge/showProblem.do?problemCode=3537
这个题目要先用凸包算法判断凸包,然后再进行区间划分,进行DP
题解:
http://blog.csdn.net/dacc123/article/details/50960199

  • 6
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
区间DP是一种动态规划的方法,用于解决区间范围内的问题。在Codeforces竞赛中,区间DP经常被用于解决一些复杂的字符串或序列相关的问题。 在区间DP中,dp[i][j]表示第一个序列前i个元素和第二个序列前j个元素的最优解。具体的转移方程会根据具体的问题而变化,但是通常会涉及到比较两个序列的元素是否相等,然后根据不同的情况进行状态转移。 对于区间长度为1的情况,可以先进行初始化,然后再通过枚举区间长度和区间左端点,计算出dp[i][j]的值。 以下是一个示例代码,展示了如何使用区间DP来解决一个字符串匹配的问题: #include <cstdio> #include <cstring> #include <string> #include <iostream> #include <algorithm> using namespace std; const int maxn=510; const int inf=0x3f3f3f3f; int n,dp[maxn][maxn]; char s[maxn]; int main() { scanf("%d", &n); scanf("%s", s + 1); for(int i = 1; i <= n; i++) dp[i][i] = 1; for(int i = 1; i <= n; i++) { if(s[i] == s[i - 1]) dp[i][i - 1] = 1; else dp[i][i - 1] = 2; } for(int len = 3; len <= n; len++) { int r; for(int l = 1; l + len - 1 <= n; l++) { r = l + len - 1; dp[l][r] = inf; 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]); } } } } printf("%d\n", dp[n]); return 0; } 希望这个例子能帮助你理解区间DP的基本思想和应用方法。如果你还有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值