51Nod - 1154 回文串划分(最少回文串dp)
回文串划分
有一个字符串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输出最少的划分数量。Sample Input
abbaabaa
Sample Output
3
字符串dp。O(n^2)枚举中心点,向两边找相同字符,状态转移方程:dp[k]=min(dp[k],dp[j-1]+1)。
#include<iostream> #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> #include<string> #include<map> #include<stack> #include<queue> #include<set> #include<algorithm> #define MAX 5005 #define INF 0x3f3f3f3f #define MOD 1000000007 using namespace std; typedef long long ll; int dp[MAX]; int main() { int t,n,m,i,j,k; char s[MAX]; scanf(" %s",s+1); int len=strlen(s+1); memset(dp,INF,sizeof(dp)); dp[0]=0; for(i=1;i<=len;i++){ for(j=i,k=i;0<j&&k<=len;j--,k++){ if(s[j]==s[k]){ dp[k]=min(dp[k],dp[j-1]+1); } else break; } for(j=i,k=i+1;0<j&&k<=len;j--,k++){ if(s[j]==s[k]){ dp[k]=min(dp[k],dp[j-1]+1); } else break; } } printf("%d\n",dp[len]); return 0; }
博文系博主原创,转载请注明出处 o(* ̄▽ ̄*)ブ 更多博文源自https://www.cnblogs.com/yzm10