区间DP题目总结
Posted roni-i
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了区间DP题目总结相关的知识,希望对你有一定的参考价值。
1:给出一个括号字符串,问这个字符串中符合规则的最长子串的长度。
【分析】区间DP要覆盖整个区间,那么要求所有情况的并集。 先想出状态方程: dp[i][j]:i ~ j区间内最大匹配数目 输出:dp[0][n-1](从0开始) 区间DP最先想到的是就是: 1.边界情况初始化 2.for枚举区间长度,一般从第二个开始 3.for枚举起点 4.直接求得终点 5.若括号匹配的情况,相当于外围是ok的,继续深入看内部,左端点右移&右端点左移+2(因为外围匹配,数目+2) 6.一般情况就是枚举断点k,打擂台求匹配数目最大值 7.输出整个区间的最大匹配数
【逆序枚举区间长度】
#include<cstdio> #include<string> #include<cstdlib> #include<cmath> #include<iostream> #include<cstring> #include<set> #include<queue> #include<algorithm> #include<vector> #include<map> #include<cctype> #include<stack> #include<sstream> #include<list> #include<assert.h> #include<bitset> #include<numeric> #define debug() puts("++++") #define gcd(a,b) __gcd(a,b) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define fi first #define se second #define pb push_back #define sqr(x) ((x)*(x)) #define ms(a,b) memset(a,b,sizeof(a)) #define sz size() #define be begin() #define pu push_up #define pd push_down #define cl clear() #define lowbit(x) -x&x #define all 1,n,1 #define rep(i,x,n) for(int i=(x); i<=(n); i++) using namespace std; typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> P; const int INF = 0x3f3f3f3f; const LL LNF = 1e18; const int maxm = 1e6 + 10; const double PI = acos(-1.0); const double eps = 1e-8; const int dx[] = {-1,1,0,0,1,1,-1,-1}; const int dy[] = {0,0,1,-1,1,-1,1,-1}; int dir[4][2] = {{0,1},{0,-1},{-1,0},{1,0}}; const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; const int mod = 10056; #define inf 0x3f3f3f3f #define ll long long const int maxn = 10010; int t,n,m,a[maxn],x,y,w; int dp[110][110],ans; string s; int tot=0; /* [题意]:给出一个括号字符串,问这个字符串中符合规则的最长子串的长度。 dp[i][j]:i~j区间内最大匹配数 输出:dp[1][n] match: dp[i][j] = dp[i+1][j-1]+2; for(k:1..j) dp[i][j] = max(dp[i][j],dp[i][k]+dp[k+1][j]); ((())) ()()() ([]]) )[)( ([][][) end 6 6 4 0 6 */ bool match(int L,int R) { return s[L]==‘(‘&&s[R]==‘)‘ || s[L]==‘[‘&&s[R]==‘]‘; } int main() { while(cin>>s) { if(s=="end") break; ms(dp,0); n=s.size(); for(int i=n-1;i>=0;i--)//枚举区间长度 { for(int j=i+1;j<n;j++) { if(match(i,j)) dp[i][j]=max(dp[i][j],dp[i+1][j-1]+2); for(int k=i;k<j;k++) dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]); } } printf("%d ",dp[0][n-1]); } }
【顺序】
#include<cstdio> #include<string> #include<cstdlib> #include<cmath> #include<iostream> #include<cstring> #include<set> #include<queue> #include<algorithm> #include<vector> #include<map> #include<cctype> #include<stack> #include<sstream> #include<list> #include<assert.h> #include<bitset> #include<numeric> #define debug() puts("++++") #define gcd(a,b) __gcd(a,b) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define fi first #define se second #define pb push_back #define sqr(x) ((x)*(x)) #define ms(a,b) memset(a,b,sizeof(a)) #define sz size() #define be begin() #define pu push_up #define pd push_down #define cl clear() #define lowbit(x) -x&x #define all 1,n,1 #define rep(i,x,n) for(int i=(x); i<=(n); i++) using namespace std; typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> P; const int INF = 0x3f3f3f3f; const LL LNF = 1e18; const int maxm = 1e6 + 10; const double PI = acos(-1.0); const double eps = 1e-8; const int dx[] = {-1,1,0,0,1,1,-1,-1}; const int dy[] = {0,0,1,-1,1,-1,1,-1}; int dir[4][2] = {{0,1},{0,-1},{-1,0},{1,0}}; const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; const int mod = 10056; #define inf 0x3f3f3f3f #define ll long long const int maxn = 10010; int t,n,m,a[maxn],x,y,w; int dp[110][110],ans; string s; int tot=0; /* [题意]:给出一个括号字符串,问这个字符串中符合规则的最长子串的长度。 dp[i][j]:i~j区间内最大匹配数 输出:dp[1][n] match: dp[i][j] = dp[i+1][j-1]+2; for(k:1..j) dp[i][j] = max(dp[i][j],dp[i][k]+dp[k+1][j]); ((())) ()()() ([]]) )[)( ([][][) end 6 6 4 0 6 */ bool match(int L,int R) { return s[L]==‘(‘&&s[R]==‘)‘ || s[L]==‘[‘&&s[R]==‘]‘; } int main() { while(cin>>s) { if(s=="end") break; ms(dp,0); n=s.size(); for(int l=1;l<n;l++)//枚举区间长度 { for(int i=0;i+l<n;i++)//起点 { int j=i+l;//终点 if(match(i,j)) dp[i][j]=max(dp[i][j],dp[i+1][j-1]+2); for(int k=i;k<j;k++) dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]); } } printf("%d ",dp[0][n-1]); } }
以上是关于区间DP题目总结的主要内容,如果未能解决你的问题,请参考以下文章