HDU4628+状态压缩DP
1 /* 2 状态压缩DP 3 dp[ i ]:达到i状态的最小step。 4 题意:每次可以去掉一个回文串,求最少几步能取完。 5 */ 6 #include<stdio.h> 7 #include<string.h> 8 #include<stdlib.h> 9 #include<algorithm> 10 #include<iostream> 11 #include<queue> 12 #include<map> 13 #include<math.h> 14 using namespace std; 15 typedef long long ll; 16 //typedef __int64 int64; 17 const int maxn = 18; 18 const int inf = 0x3f3f3f3f; 19 const double pi=acos(-1.0); 20 const double eps = 1e-8; 21 int dp[ 1<<maxn ]; 22 char s[ maxn ]; 23 int state[ 1<<maxn ];//回文的状态 24 25 bool JudgeOneZero( int ss,int len ){ 26 int Index[ maxn ]; 27 int cc = 0; 28 int IndexOfString = 0; 29 while( IndexOfString<len ){ 30 if( ss%2==1 ){// 所有的 “1” 代表该位置上有字母,即这些组合是回文串 31 Index[ cc++ ] = IndexOfString; 32 } 33 ss /= 2; 34 IndexOfString++; 35 } 36 if( cc==1 ) return true; 37 int L,R; 38 L = 0; 39 R = cc-1; 40 while( L<=R ){ 41 if( s[Index[L]]!=s[Index[R]] ) return false; 42 L++; 43 R--; 44 } 45 return true; 46 }//判断s是否是回文状态 47 48 int init_state( int len ){ 49 int cnt = 0; 50 int N = 1<<len; 51 state[ cnt++ ] = 0; 52 for( int i=1;i<N;i++ ){ 53 if( JudgeOneZero( i,len )==true ){ 54 state[ cnt++ ] = i; 55 } 56 } 57 return cnt; 58 } //初始化回文的状态 59 60 bool Judge( int cur,int nxt,int len ){//当前状态cur,前一状态nxt 61 int Index[ maxn ]; 62 int cc = 0; 63 int IndexOfString = 0; 64 while( IndexOfString<len ){ 65 if( cur%2==1 ){ 66 if( nxt%2==0 ) return false; 67 }//当前状态为1,前一状态必须为1 68 if( nxt%2==0 ){ 69 if( cur%2==1 ) return false; 70 }//前一状态是0,当前状态也必须是0 71 if( cur%2==0&&nxt%2==1 ){ 72 Index[ cc++ ] = IndexOfString; 73 } 74 IndexOfString++; 75 cur /= 2; 76 nxt /= 2; 77 } 78 if( cc==1 ) return true; 79 int L,R; 80 L = 0; 81 R = cc-1; 82 //printf("cc=%d\n",cc); 83 while( L<=R ){ 84 if( s[Index[L]]!=s[Index[R]] ) return false; 85 L++; 86 R--; 87 } 88 return true; 89 } 90 91 int main(){ 92 int T; 93 scanf("%d",&T); 94 while( T-- ){ 95 scanf("%s",s); 96 int n = strlen(s); 97 int cnt = init_state( n ); 98 int N = (1<<n); 99 for( int i=0;i<N;i++ ) 100 dp[ i ] = inf; 101 dp[ N-1 ] = 0; 102 /* 103 for( int i=N-2;i>=0;i-- ){ 104 for( int j=0;j<N;j++ ){ 105 if( i==j ) continue; 106 if( Judge( i,j,n )==true ){ 107 //printf("i=%d, j=%d\n",i,j); 108 dp[ i ] = min( dp[i],dp[j]+1 ); 109 //printf("dp[%d] = %d\n\n",i,dp[i]); 110 } 111 } 112 } 113 */ 114 for( int i=N-2;i>=0;i-- ){ 115 for( int j=0;j<cnt;j++ ){ 116 if( 0==(i&state[j]) ){ 117 dp[ i ] = min( dp[i],dp[state[j]|i]+1 ); 118 } 119 } 120 } 121 printf("%d\n",dp[0]); 122 } 123 return 0; 124 }
keep moving...