POJ1185+状态压缩DP

来源:互联网 发布:界面设计软件 编辑:程序博客网 时间:2024/06/18 04:41

经典的状态压缩DP。

dp[i][j][k] = max( dp,dp[i-1][k][k2] );

k是前一行的状态,k2是前二行的状态。

/*dp[i][j][k] = max( dp,dp[i-1][k][k2] );k是前一行的状态,k2是前二行的状态。*/#include<stdio.h>#include<string.h>#include<stdlib.h>#include<algorithm>#include<iostream>#include<queue>#include<stack>#include<math.h>#include<map>using namespace std;const int maxn = 105;const int maxm = 12;const int N = 65;int mat[ maxn ],mm[ maxn ][ maxm ];int dp[ maxn ][ N ][ N ];int state[ maxn ],ones_state[ maxn ];int GetSum( int x ){int sum = 0;while( x ){if( x&1 )sum++;x>>=1;}return sum;}int init_state( int n,int m ){int M = (1<<m);int cnt =0;memset( state,0,sizeof( state ) );memset( ones_state,0,sizeof( ones_state ) );for( int i=0;i<M;i++ ){if( (i&(i<<1))==0&&(i&(i<<2))==0&&(i&(i>>1))==0&&(i&(i>>2))==0 ){state[ cnt ] = i;ones_state[ cnt++ ] = GetSum( i );}}//printf("cnt=%d\n",cnt);return cnt;}void DP( int cnt,int n,int m ){memset( dp,-1,sizeof( dp ) );for( int i=0;i<cnt;i++ ){if(( mat[0]&state[i] )==0)dp[ 0 ][ i ][ 0 ] = ones_state[ i ];}for( int i=1;i<n;i++ ){for( int j=0;j<cnt;j++ ){if( (mat[i]&state[j])==0 ){for( int k=0;k<cnt;k++ ){if( (state[j]&state[k])==0 ){for( int k2=0;k2<cnt;k2++ ){if( dp[i-1][k][k2]==-1 ) continue;if( (state[j]&state[k2])==0&&(state[k]&state[k2])==0 ){dp[i][j][k] = max( dp[i][j][k],dp[i-1][k][k2]+ones_state[j] );}}}}}}}return ;}int main(){int n,m;while( scanf("%d%d",&n,&m)==2 ){int cnt = init_state( n,m );char s[ maxm ];for( int i=0;i<n;i++ ){scanf("%s",s);for( int j=0;j<m;j++ ){if( s[j]=='P' )mm[i][j] = 1;elsemm[i][j] = 0;}}memset( mat,0,sizeof( mat ) );for( int i=0;i<n;i++ ){for( int j=0;j<m;j++ ){if( mm[i][j]==0 )mat[i] |= (1<<j);}}DP( cnt,n,m );int ans = 0;for( int i=0;i<cnt;i++ ){for( int j=0;j<cnt;j++ ){ans = max( ans,dp[n-1][i][j] );}}printf("%d\n",ans);}return 0;}