http://acm.hust.edu.cn/vjudge/contest/view.action?cid=105116#problem/B
紫书275
题意:输入一个字符,最少能划分几个回文串
分析:预处理一下,判断i,j是否为回文串;动态分析求解,dp[i] = dp[i - 1] + 1,假设i单独成为一个回文串,然后在往前找,如果j到i是回文,dp[i] = min(dp[i], dp[j - 1] + 1)
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <algorithm> 5 using namespace std; 6 const int MAX = 1000 + 10; 7 const int INF = 0x3f3f3f3f; 8 char s[MAX]; 9 int dp[MAX],len,is_h[MAX][MAX]; 10 void judge_huiwen() 11 { 12 int x,y; 13 memset(is_h, 0, sizeof(is_h)); 14 for(int i = 1; i <= len; i++) 15 { 16 x = i - 1; 17 y = i + 1; 18 while(x > 0 && y <= len && s[x] == s[y]) 19 { 20 is_h[x][y] = 1; 21 x--; 22 y++; 23 } 24 x = i; 25 y = i + 1; 26 while(x > 0 && y <= len && s[x] == s[y]) 27 { 28 is_h[x][y] = 1; 29 x--; 30 y++; 31 } 32 } 33 } 34 int main() 35 { 36 int test; 37 scanf("%d", &test); 38 while(test--) 39 { 40 scanf("%s", s + 1); 41 len = strlen(s + 1); 42 memset(dp,0,sizeof(dp)); 43 dp[1] = 1; 44 judge_huiwen(); 45 for(int i = 2; i <= len; i++) 46 { 47 dp[i] = dp[i - 1] + 1; 48 for(int j = i - 1; j > 0; j--) 49 { 50 if(is_h[j][i]) 51 { 52 dp[i] = min(dp[i], dp[j - 1] + 1); 53 } 54 } 55 } 56 printf("%d ",dp[len]); 57 } 58 return 0; 59 }