标签:
| Time Limit: 2000MS | Memory Limit: 65536K | |
| Total Submissions: 20169 | Accepted: 7805 |
Description

Input
Output
Sample Input
5 4 PHPP PPHH PPPP PHPP PHHP
Sample Output
6
状压dp,每一行有2^m种状态,然后排除不符合的,相邻两个之间距离要大于等于2,用j & j << 1 j & j << 2 来判断,每一行的状态由上两行决定,所以dp中就要包含两行的状态,才能由一个dp推到另一个dp,dp[i][j][k]表示在第i行的时候,状态为j,i-1行状态为k的最优解。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;
int Map[120][12] , state[120][100] , num[120] ;
char str[120][12] ;
int dp[120][100][100] ;
int sum(int x,int m)
{
int temp = 0 , i ;
for(i = 0 ; i < m ; i++)
if( (1<<i) & x )
temp++ ;
return temp ;
}
int main()
{
int n , m , i , j , k , l ;
scanf("%d %d", &n, &m) ;
memset(dp,0,sizeof(dp)) ;
memset(num,0,sizeof(num)) ;
for(i = 1 ; i <= n ; i++)
scanf("%s", str[i]) ;
for(i = 1 ; i <= n ; i++)
for(j = 0 ; j < m ; j++)
{
if( str[i][j] == 'P' )
Map[i][j] = 1 ;
else
Map[i][j] = 0 ;
}
num[0] = 1 ;
state[0][0] = 0 ;
int x = 1 << m ;
for(i = 1 ; i <= n ; i++)
{
for(j = 0 ; j < x ; j++)
{
if( !(j&(j<<1)) && !(j&(j<<2)) )
{
for(k = 0 ; k < m ; k++)
{
if( !Map[i][k] && (j&1<<k) > 0 )
break ;
}
if( k == m )
state[i][ num[i]++ ] = j ;
}
}
}
for(i = 0 ; i < num[1] ; i++)
{
dp[1][i][0] = sum(state[1][i],m);
}
for(i = 2 ; i <= n ; i++)
for(j = 0 ; j < num[i] ; j++)
for(k = 0 ; k < num[i-1] ; k++)
{
if( state[i-1][k]&state[i][j] )
continue ;
for(l = 0 ; l < num[i-2] ; l++)
{
if( state[i-2][l]&state[i][j] )
continue ;
dp[i][j][k] = max( dp[i][j][k],dp[i-1][k][l] ) ;
}
dp[i][j][k] += sum(state[i][j],m) ;
}
int ans = 0 ;
for(i = 0 ; i <= num[n] ; i++)
for(j = 0 ; j < num[n-1] ; j++)
ans = max( ans,dp[n][i][j] ) ;
printf("%d\n", ans) ;
return 0;
}
标签:
原文地址:http://blog.csdn.net/winddreams/article/details/42585835