http://acm.hdu.edu.cn/showproblem.php?pid=4628
状态压缩DP 时间复杂度应该是 16*(2^32)
但是运行时要远小于这个数 所以加一定剪枝就可以过
代码:
#include<iostream> #include<cstdio> #include<algorithm> #include<string> #include<cstring> #include<cmath> #include<set> using namespace std; typedef long long ll; typedef pair<double,double>ppd; const double PI = acos(-1.); const double eps = (1e-9); const int N=20; const int M=(1<<16); bool dp[N][M]; bool ok[M]; string s; char st[N]; int main() { //freopen("data.in","r",stdin); int T; scanf("%d",&T); while(T--) { int n; cin>>s; n=s.length(); int m=(1<<n); memset(ok,true,sizeof(ok)); for(int i=1;i<m;++i) { int ln=0; for(int j=0;j<n;++j) { if((i&(1<<j))) st[ln++]=s[j]; } for(int j=0;j<ln;++j) if(st[j]!=st[ln-1-j]) {ok[i]=false;break;} } memset(dp,false,sizeof(dp)); dp[0][m-1]=true; int ans=n; for(int i=0;i<n;++i) { for(int j=0;j<m;++j) if(dp[i][j]) { if(ok[j]) {dp[i+1][0]=true;break;} for(int k=j;k>0;k=j&(k-1)) if(ok[k]) dp[i+1][j^k]=true; } if(dp[i+1][0]==true) {ans=i+1;break;} } printf("%d\n",ans); } return 0; }