题目:题目链接
思路:预处理出l到r为回文串的子串,然后如果j到i为回文串,dp[i] = min(dp[i], dp[j] + 1)
AC代码:
1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include <string> 8 #include <set> 9 #include 10 #include 11 #include 12 #include 13 #include 14 15 #define FRER() freopen("in.txt", "r", stdin) 16 #define FREW() freopen("out.txt", "w", stdout) 17 #define INF 0x3f3f3f3f 18 19 using namespace std; 20 21 const int maxn = 1000 + 5; 22 23 int n, len, l, r; 24 char str[maxn]; 25 26 bool check[maxn][maxn]; 27 int dp[maxn]; 28 29 int main() 30 { 31 //FRER(); 32 scanf("%d", &n); 33 while(n--) { 34 scanf("%s", str); 35 len = strlen(str); 36 memset(check, 0, sizeof(check)); 37 38 for(int i = 0; i < len; ++i) { 39 l = r = i; 40 while(l >= 0 && r < len) { 41 if(str[l] == str[r]) { 42 check[l + 1][r + 1] = 1; 43 --l; ++r; 44 } 45 else break; 46 } 47 l = i; 48 r = i + 1; 49 50 while(l >= 0 && r < len) { 51 if(str[l] == str[r]) { 52 check[l + 1][r + 1] = 1; 53 --l; ++r; 54 } 55 else break; 56 } 57 } 58 59 memset(dp, 0, sizeof(dp)); 60 for(int i = 1; i <= len; ++i) { 61 dp[i] = dp[i - 1] + 1; 62 for(int j = 1; j < i; ++j) { 63 if(check[j][i]) 64 dp[i] = min(dp[i], dp[j - 1] + 1); 65 } 66 } 67 68 printf("%d\n", dp[len]); 69 } 70 return 0; 71 }