1154 回文串划分
基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 收藏 关注
有一个字符串S,求S最少可以被划分为多少个回文串。
例如:abbaabaa,有多种划分方式。
a|bb|aabaa - 3 个回文串
a|bb|a|aba|a - 5 个回文串
a|b|b|a|a|b|a|a - 8 个回文串
其中第1种划分方式的划分数量最少。
Input
输入字符串S(S的长度<= 5000)。
Output
输出最少的划分数量。
Input示例
abbaabaa
Output示例
3
也是水题吧 实现有点技巧
暴力的找 更新最小值
dp[i]代表字符串到i最小分配的数量
dp[i]的来源有两个,当前的最小值,和回文串前的最小值。
每次查找到就更新
因为用了manacher 所以 对dp数组进行扩充。
#include<iostream>
#include<algorithm>
using namespace std;
int dp[15005];
int main()
{
string s;
while(cin>>s)
{
dp[0]=0;
string a;
a="!";
for(int i=0;s[i];i++)
{
a+='#';
a+=s[i];
} a+="#";
for(int i=0;a[i];i++)
{
dp[i]=(i)/2;
//cout<<dp[i]<<' '<<' '<<a[i]<<endl;
}//cout<<endl;
//cout<<a<<endl;
int minx=1000000000;
for(int i=2;a[i];i++)
{
int l=0;
while(i-l>=0&&a[i+l]==a[i-l])
{
int x=i+l;
int y=i-l;
dp[x]=min(dp[x],dp[y]+1);
l++;
//cout<<x<<' '<<dp[x]<<' '<<y<<' '<<dp[y]<<endl;
}
}
//cout<<s.size()<<' '<<dp[2]<<endl;
cout<<dp[a.size()-1]<<endl;
}
}