AGC056B Range Argmax
Description
给定 个区间 ,求有多少个 满足存在一个 的排列 使得
Solution
找到最小的 满足存在一个 且所有包含 的区间的 都是 ,这里如果任选 会导致重复计算
由于本题是数下标组而不是元素本身,那么可以将剩下待确定的 变成子问题
需要注意的是, 这部分的子问题和原问题是完全一致的,都是要求被 包含的 的 且没有额外的限制
但是 这部分需要满足所有包含 的元素的区间的最大值必须要是 ,也就是在 这个子区间选择新的 时要满足该元素处在全局所有包含 的区间的最小左端点以右,否则上一步 的选择是非法的
也就是说,如果预处理 mn[l][r][k]
表示所有 包含的 中包含 的最小值那么
设 表示区间 的局部问题中选中的 的情况下会生成多少种 ,本质上是一个后缀和,而不对 加以限制的信息就可以取
此时转移式便成了:
Code
const int N=310;
int mn[N][N][N],dp[N][N][N],n,m;
bool vis[N][N];
signed main(){
n=read(); m=read();
rep(i,1,m){
int l=read(),r=read();
vis[l][r]=1;
}
for(int i=n;i>=1;--i){
for(int j=i;j<=n;++j){
for(int k=i;k<=j;++k){
mn[i][j][k]=k;
if(k>=i+1) ckmin(mn[i][j][k],mn[i+1][j][k]);
if(k<=j-1) ckmin(mn[i][j][k],mn[i][j-1][k]);
if(vis[i][j]) mn[i][j][k]=i;
}
}
}
rep(i,0,n) dp[i+1][i][i+1]=1;
for(int i=n;i>=1;--i){
for(int j=i;j<=n;++j){
for(int t=j;t>=i;--t){
dp[i][j][t]=add(dp[i][j][t+1],mul(dp[i][t-1][mn[i][j][t]],dp[t+1][j][t+1]));
}
}
}
print(dp[1][n][1]);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律