SDOI2021集训 R1 半夜 题解


\(O(n^3)\):对 \(XX\) 每个长度为 \(n\) 的字串与 \(Y\) 跑 LCS。设 \(f[i,j,k]\) 表示 \(X[i..j],Y[1..k]\) 的 LCS,暴力转移:\(f[i,j,k]=\max(f[i,j-1,k],f[i,j,k-1],[X[j]=Y[i]](f[i,j-1,k-1]+1))\)。
考虑两个性质:
\]
\]
证明没看懂,这里提供感性理解:
\(f[i-1,j,k]>f[i-1,j-1,k]\) 说明 \(X[j]\) 可以与 \(Y\) 中一个元素匹配,那么移动 \(i\) 对其他部分的影响相同,且不会影响它,那么 \(f[i,j,k]\) 仍 \(>f[i,j-1,k]\),第二个同理。
通过这两个性质可以发现一定存在分割点 \(p[j,k],q[j,k]\) 使 \(f[i,j,k]=f[i,j-1,k]+[i>p[j,k]]=f[i,j,k-1]+[i<q[j,k]]\),用 \(p[j,n]\) 就能 \(O(n^2)\) 递推出 \(f[i,i+n-1,n]\)。
注意这里 \(p,q\) 的两维与上两篇是反的,边界也不太相同。
考虑如何求 \(p,q\)。
设 \(F=f[i,j-1,k-1],P=p[j-1,k],Q=q[j,k-1]\)。分类讨论:
- \(X[j]\neq Y[k]\)
- \(P<Q\)
| \(i\) | \(P\) | \(Q\) | |
|---|---|---|---|
| \(f[i,j-1,k]\) | \(F+1\) | \(F+1\) | \(F\) |
| \(f[i,j,k-1]\) | \(F\) | \(F+1\) | \(F+1\) |
| \(f[i,j,k]\) | \(F+1\) | \(F+1\) | \(F+1\) |
其中 \(f[i,j,k]\) 的取值是根据最开始的暴力 DP 转移得到的,根据 \(f[i,j,k]\) 的取值就能得出 \(p[j,k]=Q,q[j,k]=P\)
其余三类也可以写出类似的表格,注意 \(X[j]=Y[k]\) 时 \(f[i,j,k]=f[i,j-1,k-1]+1\),这里就不一一列出了。
代码异常简洁:
const int N = 4e3+5;
int n;
char a[N],b[N];
int m,ans,p[N][N],q[N][N];
signed main() {
scanf("%d%s%s",&n,a+1,b+1); m = n+n; memcpy(a+n+1,a+1,n);
For(j,1,m) p[j][0] = j;
For(j,1,m) For(k,1,n) {
int P = p[j][k-1], Q = q[j-1][k];
if( a[j] != b[k] && P > Q ) p[j][k] = P, q[j][k] = Q;
else p[j][k] = Q, q[j][k] = P;
}
For(i,1,n) {
int now = 0;
For(j,i,i+n-1) now += i>p[j][n];
ckmax(ans,now);
}
write(ans);
return iocl();
}
SDOI2021集训 R1 半夜 题解的更多相关文章
- HihoCoder1338 A Game (区间DP)
<题目链接> 题目大意: 两个人轮流从一个序列中取数,他们都面临同样的二选一决策:是拿走最左边的数,还是拿走最右边的数?问先手最多能够得到的分数是多少. 解题分析: 一道比较经典的DP,因 ...
- 【题解】P4247 [清华集训]序列操作(线段树修改DP)
[题解]P4247 [清华集训]序列操作(线段树修改DP) 一道神仙数据结构(DP)题. 题目大意 给定你一个序列,会区间加和区间变相反数,要你支持查询一段区间内任意选择\(c\)个数乘起来的和.对1 ...
- 【某集训题解】【DAY 2 T3】与非
题目描述 作为一名新世纪共产主义的接班人,你认识到了资本主义的软弱性与妥协性,决定全面根除资本主义,跑步迈入共产主义.但是当你即将跨入共产主义大门的时候,遇到了万恶的资本家留下的与非电路封印,经过千辛 ...
- Nowcoder | [题解-N165]牛客网NOIP赛前集训营-普及组(第二场)
啊...表示一大早还没睡醒就开始打比赛(开始前一分钟的我还在桌子上趴着休眠)...表示题目思路清奇(尤其C题)...但是我还是太蒻了...\(D\)题暴力都没打...题解正式开始之前先\(\%\)一下 ...
- R1题解
估分 大佬们都去写题解了,我不写可能会被老师训诶.... 预计分数:100 + 100 + 5 + 100 + 25 + 100 = 430 实际 :80 + 100 + 0 + 100 + 25 + ...
- 暑假集训——cf热身赛部分题有感加其题解
刚刚开始集训,集训队队长暂时还没有拉专题,而是拉了部分codeforces上过题人数在2000左右的题组成了一场热身赛(其实就是一场练习),花了一天时间终于把它刷完了,其中很多题让我学到了很多骚操作, ...
- Yali7月集训Contest2 T1 Cube 题解
题目链接: 连我们都只有纸质题目...话说雅礼集训都是这样的吗... 大意 0维基本图形是一个点 1维基本图形是一条线段 2维基本图形是一个正方形 3维基本图形是一个正方体 4维基本图形是... 求\ ...
- SUST_ACM_2019届暑期ACM集训热身赛题解
问题A:Hello SUST! 知识点:基本输入输出 C/C++: #include <stdio.h> int main() { int n; scanf("%d", ...
- HZNU-ACM寒假集训Day12小结 数论入门 题解
算不出的等式 BJOI2012 看到这题 真没什么办法 无奈看题解 1.注意到p/q 联想到斜率 2.注意到 [ ] 联想到整点 注意到k在变化,构造一次函数 f(x)=p/q*x ,g(x)=q/p ...
随机推荐
- 如何开启MySQL远程连接
MySql-Server 出于安全方面考虑只允许本机(localhost, 127.0.0.1)来连接访问,这对于 Web-Server 与 MySql-Server 都在同一台服务器上的网站架构来说 ...
- Netty基础招式——ChannelHandler的最佳实践
本文是Netty系列第7篇 上一篇文章我们深入学习了Netty逻辑架构中的核心组件EventLoop和EventLoopGroup,掌握了Netty的线程模型,并且介绍了Netty4线程模型中的无锁串 ...
- C++ 1 (只在源文件)//点和圆的关系 //设计一个圆形类 和一个点类 计算点和圆的关系 //点到圆心的距离 == 半径 点在圆上 //点到圆心的距离 > 半径 点在圆外 //点到圆心的距离 < 半径 点在圆内 //点到圆心的距离 获取 ....... (x1 -x2)^2 + (y1-y2)^2 开根号 和半径对比 // 计算 可以 两边同时 平方
1 //点和圆的关系 2 //设计一个圆形类 和一个点类 计算点和圆的关系 3 //点到圆心的距离 == 半径 点在圆上 4 //点到圆心的距离 > 半径 点在圆外 5 //点到圆心的距离 &l ...
- C++1-100之间 7的倍数 带7 打印 敲桌子
1 // 1-100之间 7的倍数 带7 打印 敲桌子 2 #include <iostream> 3 using namespace std; 4 5 int main() 6 { 7 ...
- 密码三次就会锁掉 while 循环
while 只要给定的条件为真,C 语言中的 while 循环语句会重复执行一个目标语句 一般定义 //return_type function_name( parameter list ) //{ ...
- CentOS的crond系统定时服务
crond 服务管理 [root@node01 ~]# service crond start (启动服务) [root@node01 ~]# service crond stop ...
- zookeeper的集群搭建
.personSunflowerP { background: rgba(51, 153, 0, 0.66); border-bottom: 1px solid rgba(0, 102, 0, 1); ...
- 01 CTF从0到。。。。
无意间在前段时间接触到了CTF,感觉很有意思,就参加了个单位的短期培训,并且参加了比赛,也是无意混进了决赛.感觉自己不会的还很多!SO,开始写博客开始刷题,自己很菜,不会C,不会Python,不会汇编 ...
- 答应我,安装chromedriver,按照版本号,v70就安装v2.42,
下载chromedriver,链接:http://chromedriver.storage.googleapis.com/index.html ----------ChromeDriver v2.42 ...
- 题解—P2898 [USACO08JAN]Haybale Guessing G
pre 首先注意一下翻译里面并没有提到的一点,也是让我没看懂样例的一点,就是这个长度为 \(n\) 的数组里面的数各不相同. 有很多人用并查集写的这道题,题解里面也有一些用线段树写的,不过我认为我的做 ...