1154 回文串划分(DP+Manacher)
Posted happy_code
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1154 回文串划分(DP+Manacher)相关的知识,希望对你有一定的参考价值。
基准时间限制: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
相关问题
最长回文子串 V2(Manacher算法) 最长回文子串 回文串划分 V2 6
40
回文字符串 10//显然dp,dp[i] 表前 i 个数最少能变几个回文
dp[i] = min(dp[i], dp[z-1]+1) "s[z],s[z+1]...s[i]" 是一个回文串
用马拉车就是 n*2n ,5000*10000,话说弱鸡我debug一万年。。。
不用就是 n^3 吧,不大懂
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define LL long long 4 #define MOD 1000000007 5 #define MX 5005 6 7 int n; 8 int len; 9 char temp[MX]; 10 char str[MX*2]; 11 int p[MX*2]; 12 int dp[MX*2]; 13 14 void Init() 15 { 16 len = 0; 17 str[len++]=‘@‘; 18 str[len++]=‘#‘; 19 n = strlen(temp); 20 for (int i=0;i<n;i++) 21 { 22 str[len++]=temp[i]; 23 str[len++]=‘#‘; 24 } 25 memset(p,0,sizeof(p)); 26 } 27 28 void Manacher() 29 { 30 Init(); 31 int mx = 0, id =0; 32 for (int i=1;i<len;i++) 33 { 34 p[i] = mx>i ? min(p[2*id-i],mx-i):1; 35 while (str[i+p[i]]==str[i-p[i]]) p[i]++; 36 if (i+p[i]>mx) 37 { 38 mx = i+p[i]; 39 id = i; 40 } 41 } 42 } 43 44 int main() 45 { 46 while (scanf("%s",temp)!=EOF) 47 { 48 Manacher(); 49 50 for (int i=0;i<n;i++) 51 { 52 dp[i] = i+1; //初值 53 int pos = (i+1)*2; 54 for (int j=pos;j>=1;j--) 55 { 56 if(j+p[j]-2>=pos) 57 { 58 int pre = (j-(pos-j))/2-1; 59 if (pre==0) dp[i]=1; 60 else dp[i]= min(dp[pre-1]+1,dp[i]); 61 } 62 } 63 } 64 printf("%d\n",dp[n-1]); 65 } 66 return 0; 67 }
以上是关于1154 回文串划分(DP+Manacher)的主要内容,如果未能解决你的问题,请参考以下文章
HDU 3068 &&HDU 3294 +最长回文串*3—— manacher/扩展KMP/DP
bzoj 3790 神奇项链(Manacher,DP+BIT | 贪心)