/**
UVA - 11584 划分字符串的回文串子串; 简单dp题目大意:给一个字符串, 要求把它分割成若干个子串,使得每个子串都是回文串。问最少可以分割成多少个。定义:dp[i]表示前0~i内的字符串划分成的最小回文串个数;dp[i] = min(dp[j]+1 | j+1~i是回文串);先预处理flag[i][j]表示以i~j内的字符串为回文串;可以通过遍历字符串中心来处理;*/#include<iostream>#include<cstring>#include<cstdio>#include<string>#include<set>#include<algorithm>#include<vector>#include<map>#include<queue>#include<cmath>#include<cctype>#include<stack>#include<iomanip>using namespace std;typedef pair<int,int> pr;const int maxn = 1005;const int inf = 0x3f3f3f3f;char s[maxn];bool flag[maxn][maxn];int dp[maxn], ls;void dfs(int i,int j){ if(i==0||j>ls) return ;
if(s[i]==s[j]){
flag[i][j] = true;
dfs(i-1,j+1);
}
}int main(){ int T;
cin>>T;
while(T--)
{
scanf("%s",s+1);
ls = strlen(s+1);
// cout<<"ls = "<<ls<<endl;
memset(flag,false,sizeof flag);
for(int i = 1; i <= ls; i++){
flag[i][i] = true;
dfs(i,i+1);//令i为偶数回文串中心的左边那个;
dfs(i-1,i+1); //令i为奇数回文串中心的中间那个;
// dfs(i-1,i); 不需要令i为偶数回文串中心的右边那个,因为已经令i为偶数回文串中心的左边那个;中包含了;
}/*
for(int i = 1; i <= ls; i++){
for(int j = 1; j <= ls; j++){
cout<<"i = "<<i<<"j = "<<j<<"flag[i][j] = "<<flag[i][j]<<endl;
}
}*/
for(int i = 1; i <= ls; i++) dp[i] = inf;
dp[0] = 0;
for(int i = 1; i <= ls; i++){
for(int j = 0; j < i; j++){
if(flag[j+1][i])
dp[i] = min(dp[i],dp[j]+1);
}
}
// for(int i = 1; i <= ls; i++) cout<<"dp[i] = "<<dp[i]<<endl;
printf("%d\n",dp[ls]);
}
return 0;
}