Link:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1154
#include <bits/stdc++.h> using namespace std; /* 题意:有一个字符串S,求S最少可以被划分为多少个回文串。 题解:暴力预处理出每位能到达范围,dp可以由当前处理位置选择多长回文串转移。 */ const int N = 5005; const int INF = 0x3f3f3f3f; int ma[N],mb[N],len; char s[N]; void Ma(int x){ int i = 1; while(x-i>=1 && x+i<=len && s[x+i] == s[x-i]) i++; ma[x] = i-1; //两边ma[i] } void Mb(int x){ int i = 1; while(x-i+1>=1 && x+i<=len && s[x-i+1] == s[x+i]) i++; mb[x] = i-1; //左边mb[i]-1,右边mb[i] } int dp[N]; //处理到i为中心的回文串 的最小划分数 int main(){ scanf("%s",s+1); len = strlen(s+1); //printf("%d\n",len); for(int i = 1; i <= len; i++){ Ma(i); Mb(i); dp[i] = i; } dp[0] = 0; for(int i = 1; i <= len; i++){ for(int j = 0; j <= ma[i]; j++) dp[i+j] = min(dp[i+j],dp[i-j-1]+1); for(int j = 1; j <= mb[i]; j++) dp[i+j] = min(dp[i+j],dp[i-j]+1); } // for(int i = 1; i <= len; i++) // printf("%d\n",dp[i]); printf("%d\n",dp[len]); return 0; }