「山东省队集训2021 Round 1」 半夜
考虑将 复制一次放到后面再对其长度为 的连续子串和 求一波 就能得到 的分数了
那么设 表示 的
考虑如下两个性质:
下文受篇幅限制只证明第一个:
因为这个 类似于网格图上最大带权游走,那么设两个串的左端点为网格图起始点,右端点为终止点
不难发现两条路径必然存在交点,设 到 的 最靠左 路径为 ,而 到 的最靠左的最优路径为
设两个路径公共部分是 ,之前是 ,之后的是 ,把已知和结论统统表示出来互相推就行了
那么必然存在 满足:
至此可以得到所有 然后使用第一个等号后的式子递推 即可
考虑如何转移 ?
设 (认真注意变量定义)
-
如果 ,把 的转移结果写出来就能发现 ,因为
而对于 的情况,仍然是写出来转移的结果得到
-
这里必然会有 ,那么分开讨论究竟是哪边加了 ,对转移有贡献的如下:
如果 ,即上次不能转移,但是现在可以,那么必然满足
如果 ,即提前转移过了,现在不能转移,那么必然满足
这样就可以了! 时间复杂度
const int N=2010;
int p[N][N<<1],q[N][N<<1],f[N<<1][N<<1],n,ans;
char x[N<<1],y[N];
signed main(){
n=read(); scanf("%s%s",x+1,y+1); rep(i,1,n) x[i+n]=x[i];
rep(i,1,n*2) p[0][i]=i+1; rep(i,1,n*2) q[0][i]=1;
rep(i,1,n) rep(j,1,(n<<1)){
int P=p[i-1][j],Q=q[i][j-1];
if(P>=Q&&x[j]!=y[i]) p[i][j]=P,q[i][j]=Q;
else p[i][j]=Q,q[i][j]=P;
}
rep(i,0,(n<<1)) rep(j,i,(n<<1)) f[i][j]=f[i][j-1]+(i>=p[n][j]);
rep(i,1,n) ckmax(ans,f[i][i+n-1]); print(ans); return 0;
}
//Use The Time To Enrich This Selfclosing Youth
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律