這是一個大水題啊。。。
因爲比賽時不會算複雜度耽誤半天。
i從0到2^n枚舉集合i的所有分割兩半的情況的複雜度爲O(3^n),可以想象這個過程相當於是給每個位標記0,1,2(0表示不選,1,2表示兩個集合)
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
char s[20];
int vis[1<<16];
int main(){
int t,T,i,j,len;
scanf("%d",&T);
for(t=1;t<=T;t++){
scanf("%s",s);
len=strlen(s);
for(i=1;i<(1<<len);i++){
bool flag=1;
int l=0,r=len-1;
while(l<r){
while(l<len && ((i&(1<<l))==0))
l++;
while(r>=0 && ((i&(1<<r))==0))
r--;
if(s[l]!=s[r]){
flag=0;
break;
}
l++,r--;
}
if(flag) vis[i]=1;
else vis[i]=len;
}
for(i=1;i<(1<<len);i++){
if(vis[i]==1)continue;
for(j=(i-1)&i;j;j=(j-1)&i) vis[i]=min(vis[i],vis[i-j]+vis[j]);
}
printf("%d\n",vis[(1<<len)-1]);
}
}