这道题写的我直吐血,写了6遍,不知道哪里错了,然后按照题解,一点一点写下来,跪哭了,太渣了 :(
PS:http://blog.csdn.net/cq_pf/article/details/41931061
#include<iostream>
#include<cstdio>
#include<string.h>
#include<string>
#include<stack>
#include<set>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>
#include<set>
#define ll __int64
#define lll unsigned long long
#define llf long double
#define db double
#define MAX 600
#define eps 1e-8
#define mod 100000000
using namespace std;
/*
dp[i][j][k] = max(dp[i][j][k],dp[i-1][j][k]);
第i行的状态为k,第i-1行的状态为j
H = 1 P = 0
那么判断所选状态能否在该行可行的条件就是‘&’是否为0
*/
int dp[109][109][109];//dp方程
int stk[600];//状态数
int num[600];//1的个数
int ma[509];//每行的状态
char str[109][20];//字符串
int n,m;
int lr(int x)
{
if(x&x<<1) return 0;
if(x&x<<2) return 0;
return 1;
}
int _sum(int x)//数一个整型数x的二进制中1的个数(用于初始化)
{
int cnt = 0;
while(x)
{
cnt++;
x&=(x-1);
}
return cnt;
}
int init()
{
int top = 0;
int ss = 1<<m;
for(int i = 0; i<ss; i++)
{
if(lr(i))
{
stk[top++] = i;
}
}
return top;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
memset(dp,-1,sizeof(dp));
for(int i = 0;i<n;i++)
{
scanf("%s",str[i]);
ma[i] = 0;
for(int j = 0;j<m;j++)
{
if(str[i][j]=='H')
ma[i]+=(1<<j);
}
}
int top = init();
for(int i =0;i<top;i++)
{
if(!(ma[0]&stk[i]))
{
dp[0][0][i] = _sum(stk[i]);
}
}
for(int i = 1;i<n;i++)
{
for(int j = 0 ;j<top;j++)//枚举第i行的情况
{
if(ma[i]&stk[j])continue;//判断是否该状态是否在这一行可行
for(int k = 0;k<top;k++)//枚举第i-1的情况
{
if(stk[j]&stk[k])continue;//判断该列是否与前一列冲突
for(int t = 0;t<top;t++))//枚举第i-2的情况
{
if(stk[j]&stk[t])continue;)//判断该列是否与前两列冲突
if(dp[i-1][t][k]==-1)continue;//判断dp[i-1][s][j]是否有可能到达
dp[i][k][j] = max(dp[i][k][j],dp[i-1][t][k]+_sum(stk[j]));
}
}
}
}
int _max = 0;
for(int i = 0;i<top;i++)
{
for(int j = 0;j<top;j++)
{
_max = max(_max,dp[n-1][i][j]);
}
}
cout<<_max<<endl;
}
return 0;
}