HDU 4628

这是一个大水题啊。。。

因为比赛时不会算复杂度耽误半天。

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]);
    }
}


 

 

posted on 2013-07-31 19:47  you Richer  阅读(208)  评论(0编辑  收藏  举报