题解 [POI2005] SZA-Template

题目链接

充分暴露出对 border 结合 dp 理解的不足。

先来推结论,一个字符串的印章一定是其 border,因为只有这样才可能兼顾首尾,但是他的 border 不一定是其印章,两个条件不能互推。

dpi 表示前 i 个字符串的最小印章长度。现在考虑如何转移。

dpi 的取值只有可能是 idpfailii 就是取自己为印章,dpfaili 表示先将其 border 想办法填出来,然后再在末尾加上剩余字符。

那么什么时候能从 dpfaili 转移过来呢,首先找到一个最大的
dpj=dpfaili,由于在 j 后面我们至多填上 dpfaili 长度的字符串,所以当 ijdpfaili 时,可以转移。对于合法的 j,维护一个 dp 值对应的最大下标即可。

点击查看代码
const int N=5e5+10;
string s;
int n;
int fail[N];
int maxp[N],dp[N];
int main() {
cin>>s;
n=s.size(); s=" "+s;
for(int i=2;i<=n;i++) {
int j=fail[i-1];
while(s[j+1]!=s[i]&&j) j=fail[j];
if(s[j+1]==s[i]) fail[i]=j+1;
}
for(int i=1;i<=n;i++) {
dp[i]=i;
maxp[dp[i]]=i;
if(!dp[fail[i]]) continue;
if(i-maxp[dp[fail[i]]]<=dp[fail[i]]) {
dp[i]=dp[fail[i]];
maxp[dp[i]]=i;
}
}
cout<<dp[n];
return 0;
}
posted @   2017BeiJiang  阅读(15)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
点击右上角即可分享
微信分享提示