题意:
给出一个字符串,求这个字符串可以被划分为最少的回文串的个数。
思路:
首先可以N^2预处理出i到j是不是一个回文串。
之后就是状态转移方程:
dp[i] = min(dp[j-1] + 1,dp[i]),如果s[j..i]是回文串。
代码:
1 #include <stdio.h> 2 #include <string.h> 3 #include <algorithm> 4 #include <iostream> 5 #include <string> 6 using namespace std; 7 const int N = 1005; 8 const int inf = 0x3f3f3f3f; 9 bool dp[N][N]; 10 int num[N]; 11 char s[N]; 12 int main() 13 { 14 int n; 15 scanf("%d",&n); 16 while (n--) 17 { 18 memset(dp,0,sizeof(dp)); 19 memset(num,inf,sizeof(num)); 20 scanf("%s",s+1); 21 int m = strlen(s+1); 22 num[0] = 0; 23 for (int i = 1;i <= m;i++) dp[i][i] = 1; 24 for (int i = 1;i <= m;i++) 25 { 26 int l = i,r = i; 27 while (l >= 1 && r <= m && s[l] == s[r]) 28 { 29 dp[l][r] = 1; 30 l--,r++; 31 } 32 if (i == m) continue; 33 if (s[i] != s[i+1]) continue; 34 l = i,r = i+1; 35 while (l >= 1 && r <= m && s[l] == s[r]) 36 { 37 dp[l][r] = 1; 38 l--,r++; 39 } 40 } 41 for (int i = 1;i <= m;i++) 42 { 43 for (int j = i;j >= 1;j--) 44 { 45 if (dp[j][i]) num[i] = min(num[i],num[j-1]+1); 46 } 47 } 48 printf("%d\n",num[m]); 49 } 50 return 0; 51 }