题意:给你一个串,问最少能划分成几个回文串。
例如:racecar本身就是回文串,只用一个划分。
思路:这题定义d[i]表示:0~i字符串的最小回文串的个数,则dp[i]=min(dp[j]+1);s[j][i]满足回文串的条件。
所以这题需要预先处理s[i][j]判断某个子串是不是回文串,时间复杂度O(n^2);转移方程也是O(n^2);
#include<bits/stdc++.h>
using namespace std;
const int inf=0x7ffffff;
int s[1010][1010],dp[1010];
char str[1010];
int main(){
int t;scanf("%d",&t);
while(t--){
scanf("%s",str+1);
memset(s,0,sizeof(s));
int n=strlen(str+1);
for(int i=1;i<=n;i++) s[i][i]=1;
for(int i=1;i<=n;i++){
int j=1;
while(i-j>=0&&i+j<=n){
if(str[i-j+1]==str[i+j]) { s[i-j+1][i+j]=1;j++;}
else break;
}
j=1;
while(i-j>=1&&i+j<=n){
if(str[i+j]==str[i-j]) { s[i-j][i+j]=1;j++;}
else break;
}
}
for(int i=1;i<=n;i++) dp[i]=i;
dp[0]=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=i;j++){
if(s[j][i]) dp[i]=min(dp[i],dp[j-1]+1);
}
}
printf("%d\n",dp[n]);
}
}