卡特兰数 题解
bsoj7107 ,来源不明。
卡特兰数
题目描述
今天,接触信息学不久的小A刚刚学习了卡特兰数。
卡特兰数的一个经典定义是,将 个数依次入栈,合法的出栈序列个数。
小A觉得这样的情况太平凡了。于是,他给出了 组限制,每个限制形如 ,表示 不能在 之后出栈。
他想求出:在满足了这 组限制的前提下,共有多少个合法的出栈序列。他不喜欢大数,你只需要求出答案在模 意义下的值即可。
输入格式
输入第一行为两个非负整数 、 ,含义题面已给出。
接下来 行,每行两个正整数, 表示一组限制。
输出格式
输出一行,为一个非负整数,表示你求得的答案 。
样例输入
3 1 2 3 样例输出
3 样例解释
可以验证 , , 都是合乎条件的。
数据规模
, , 。
部分数据的 较小。
考前一天写题解会不会涨RP
套路但是还是感觉很巧妙的转换。关键在于把限制形式化的写出来方便观察。
考虑Catalan数的递推公式推导方式——枚举最后出栈的元素 。其递推式为
加入限制后无法使用排列的相对顺序dp,故需改造原来的递推。定义 为排列 不同的出栈序列方案数,若暂不考虑限制,有
显然 。
递推中,出栈序列的相对顺序为 。限制 要求 在 之前出栈。故满足 或者 的 都不合法,不应对 产生贡献。故在此dp中枚举所有限制判断合法性即可获得 的算法。
这种方法看着就很naive,考虑优化合法性判断。容易发现把 投到二维平面上后,判断合法性只需询问 、 两个矩形中是否有点。二维前缀和处理即可 判断。于是这样就可以 通过本题了。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> using namespace std; typedef long long ll; ll Rd(){ ll ans=0;bool fh=0;char c=getchar(); while(c<'0'||c>'9'){if(c=='-') fh=1; c=getchar();} while(c>='0'&&c<='9') ans=ans*10+c-'0',c=getchar(); if(fh) ans=-ans; return ans; } const ll MOD=998244353; #define _ %MOD ll PMod(ll x){ if(x>=MOD) return x-MOD; else if(x<0) return x+MOD; else return x; } const ll MXN=305; ll N,M; ll A[MXN][MXN]; ll S[MXN][MXN]; void SpawnSum(){ for(ll i=1;i<=N;i++) for(ll j=1;j<=N;j++) S[i][j]=S[i-1][j]+S[i][j-1]-S[i-1][j-1]+A[i][j]; } bool Check(ll x1,ll y1,ll x2,ll y2){ return S[x2][y2]-S[x1-1][y2]-S[x2][y1-1]+S[x1-1][y1-1]; } ll f[MXN][MXN]; void Solve(){ for(ll i=0;i<=N;i++) f[i+1][i]=1; for(ll len=1;len<=N;len++){ for(ll l=1;l+len-1<=N;l++){ ll r=l+len-1; for(ll k=l;k<=r;k++){ if(Check(k,l,r,k-1)) continue; if(Check(k,k+1,k,r)) continue; f[l][r]=(f[l][r]+f[l][k-1]*f[k+1][r])_; } } } cout<<f[1][N]; } int main(){ N=Rd();M=Rd(); for(ll i=0;i<=N;i++) for(ll j=0;j<=N;j++) A[i][j]=S[i][j]=0; for(ll i=1;i<=M;i++){ ll x=Rd(),y=Rd(); A[x][y]=1; } SpawnSum(); Solve(); return 0; }
2020/12/04
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现