题意:给出一个字符串,求能最少划分成几个连续子串,使得每个子串都是回文串.
思路:设dp[i]为前i个字符划分的最优解,
那么dp[i] = min(dp[i], dp[j] + 1)这里满足满足j + 1..i为一个回文串.
可以用一个二维数组预处理求出x...y的串是否为回文串来做.
#include <cstdio>
#include <algorithm>
#include <memory.h>
using namespace std;
const int MAX = 1002;
bool is_palin[MAX][MAX];
int dp[MAX];
char str[MAX];
int main(int argc, char const *argv[]){
int T;
scanf("%d", &T);
while(T--){
scanf("%s", str + 1);
int n = strlen(str + 1);
memset(is_palin, false, sizeof(is_palin));
for(int i = 1; i <= n; ++i){
is_palin[i][i] = true;
for(int j = 1; i - j >= 1 && i + j <= n && str[i - j] == str[i + j]; ++j){
is_palin[i - j][i + j] = true;
}
for(int j = 1, k = 0; i - k >= 1 && i + j <= n && str[i - k] == str[i + j]; ++j, ++k){
is_palin[i - k][i + j] = true;
}
for(int j = 0, k = 1; i - k >= 1 && i + j <= n && str[i - k] == str[i + j]; ++j, ++k){
is_palin[i - k][i + j] = true;
}
}
for(int i = 1; i <= n; ++i){
dp[i] = i;
for(int j = 0; j < i; ++j){
if(is_palin[j + 1][i]){
dp[i] = min(dp[i], dp[j] + 1);
}
}
}
printf("%d\n", dp[n]);
}
return 0;
}