题解 [CSP-S 2021] 括号序列
对于括号题,基本是栈匹配没有匹配的左括号和区间 两个方向。这道题括号序列并不确定,只能用区间 搞。
如果直接设 表示 的合法括号序列,那么由区间 的套路可知,需要枚举中间点进行合并,那么 的情况就会出问题,原因是第一次将 与 合并,第二次将 和 进行合并,计算重复。
为了解决这个问题,我们规定只将 与 进行合并,也就是先将括号序列分成两类,分别是 两边括号匹配,和两边括号不匹配,计作 ,那么合并时将 合并到 上即可。接下来推 方程。
判断连续段能否被完全填充,可以采取前缀和的方式,若一段内 的总和等于段长且不超过给定数量。
左右括号能匹配的:
:长度为 ,将 即可。
:若中间可以由连续的 填充,则将 。
:枚举 的断点 ,那么 。
:枚举 的断点,
左右括号不能匹配的:
:令 $B=f,枚举断点 ,那么 。
:可以先处理出 的 数量,计作 ,然后用 更新 ,
代码:
#include<bits/stdc++.h> using namespace std; typedef long long LL; #define PII pair<int,int> LL read() { LL sum=0,flag=1; char c=getchar(); while(c<'0'||c>'9') {if(c=='-') flag=-1; c=getchar();} while(c>='0'&&c<='9') {sum=sum*10+c-'0'; c=getchar();} return sum*flag; } const int N=510; const LL MOD=1e9+7; int n,m; int sum[N]; string s; LL f[N][N],g[N][N],h[N][N]; //合法,左右括号匹配,左右括号不匹配,SA的数量 int pd(int l,int r) { if(sum[r]-sum[l-1]<=m&&sum[r]-sum[l-1]==r-l+1) return 1; else return 0; } int check(int l,int r) { if(s[l]=='('&&s[r]==')') return 1; if(s[l]=='?'&&s[r]==')') return 1; if(s[l]=='('&&s[r]=='?') return 1; if(s[l]=='?'&&s[r]=='?') return 1; return 0; } int main() { cin>>n>>m; cin>>s; s=" "+s; for(int i=1;i<=n-1;i++) { if(s[i]=='?'||s[i]=='*') sum[i]=sum[i-1]+1; else sum[i]=sum[i-1]; if(check(i,i+1)) f[i][i+1]=1; } for(int len=3;len<=n;len++){ for(int i=1;i+len-1<=n;i++) { int j=i+len-1; if(check(i,j)) { if(pd(i+1,j-1)) f[i][j]=(f[i][j]+1)%MOD; for(int k=i+1;k<=j-1;k++) { if(pd(i+1,k)) f[i][j]=(f[i][j]+f[k+1][j-1]+g[k+1][j-1])%MOD; } for(int k=j-1;k>=i+1;k--) { if(pd(k,j-1)) f[i][j]=(f[i][j]+f[i+1][k-1]+g[i+1][k-1])%MOD; } f[i][j]=(f[i][j]+f[i+1][j-1]+g[i+1][j-1])%MOD; } for(int k=i;k<=j;k++) { g[i][j]=(g[i][j]+(f[i][k]+g[i][k])*f[k+1][j])%MOD; } for(int k=i;k<=j;k++) { if(pd(i,k)) h[i][j]=(h[i][j]+f[k+1][j])%MOD; } for(int k=i;k<=j;k++) { g[i][j]=(g[i][j]+(g[i][k]+f[i][k])*h[k+1][j]%MOD)%MOD; } } } cout<<(f[1][n]+g[1][n])%MOD; return 0; }
标签:
动态规划——区间DP
, 题解
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 凌晨三点救火实录:Java内存泄漏的七个神坑,你至少踩过三个!