NC23501 小A的回文串
题目
题目描述
小A非常喜欢回文串,当然我们都知道回文串这种情况是非常特殊的。所以小A只想知道给定的一个字符串的最大回文子串是多少,但是小A对这个结果并不是非常满意。现在小A可以对这个字符串做一些改动,他可以把这个字符串最前面的某一段连续的字符(不改变顺序)移动到原先字符串的末尾。那么请问小A通过这样的操作之后(也可以选择不移动)能够得到最大回文子串的长度是多少。
输入描述
一行一个字符串表示给定的字符串S一行一个字符串表示给定的字符串S一行一个字符串表示给定的字符串S
输出描述
一行输出一个整数,表示通过这样的操作后可以得到最大回文子串的长度。
示例1
输入
dcbaabc
输出
7
说明
将前面的dcba移动到末尾变成abcdcba,这个字符串的最大回文子串就是它本身,长度为7
备注
表示字符串的长度,
题解
知识点:区间dp。
这是一道环状处理的区间dp,但注意,如果不加以优化直接加倍会产生 大小的数组会炸空间。
注意到题目要求处理的是回文子串,因此 本身直接代表是否是回文串即可。
又区间dp是按照长度为阶段进行的,因此知道一个端点就能知道另一个;同时回文子串的判断只可能从长度减 的地方传递过来,其他长度的用不到了,所以只需要保存前两次长度对应的所有区间信息即可。
有了这两个条件(缺一不可)我们可以去掉一维换成长度,即 为以 为左端点,区间长度模 为 的区间是否是回文串,循环存储信息即可,这样就能做了,细节上看代码。
时间复杂度
空间复杂度
代码
#include <bits/stdc++.h> using namespace std; bool dp[5007 << 1][3];///左端点,长度 int main() { std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); string s; cin >> s; int n = s.size(); s += s; for (int i = 0;i < 2 * n;i++) dp[i][0] = dp[i][1] = 1; int ans = 1; for (int l = 2;l <= n;l++) { for (int i = 0, j = l - 1;j < 2 * n;i++, j++) { if (s[i] == s[j] && dp[i + 1][(l + 1) % 3]) dp[i][l % 3] = 1; else dp[i][l % 3] = 0;///调零 if (dp[i][l % 3]) ans = max(ans, l); } } cout << ans << '\n'; return 0; }
本文来自博客园,作者:空白菌,转载请注明原文链接:https://www.cnblogs.com/BlankYang/p/16586915.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧