开始题目看错了....以为是连着的回文才能一次消掉..题目的意思是分开的也行...

    串最长16..很容易想到状态压缩DP....当本状态回文时..直接为1...否则是其两个相对其互补的子集并的最小值...更新的时候要枚举其所有的子集...

    比如说二进制状态t..要枚举其所有的子集..for(int i=t;i;i=(i-1)&t) 


Program:

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<algorithm>
#define ll long long
#define oo 1000000007
#define pi acos(-1.0)
#define MAXN 16
using namespace std;
char s[MAXN];
int dp[1<<MAXN],n;
bool IsPalindrome(int x)
{
char ss[MAXN];
int i,j,m;
m=0;
for (i=0;i<n;i++)
if (x & (1<<i))
ss[m++]=s[i];
i=0,j=m-1;
while (i<=j && ss[i]==ss[j]) i++,j--;
if (i>j) return true;
return false;
}
int main()
{
int T;
scanf("%d",&T);
while (T--)
{
scanf("%s",s);
n=strlen(s);
dp[0]=0;
for (int t=1;t<(1<<n);t++)
{
dp[t]=oo;
if (IsPalindrome(t)) dp[t]=1;
for(int i=t;i;i=(i-1)&t) //枚举t的所有子集
dp[t]=min(dp[t],dp[i]+dp[t^i]);
}
printf("%d\n",dp[(1<<n)-1]);
}
return 0;
}