| Time Limit: 2000MS | Memory Limit: 65536K | |
| Total Submissions: 17272 | Accepted: 6593 |
Description

Input
Output
Sample Input
5 4 PHPP PPHH PPPP PHPP PHHP
Sample Output
6
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
#include<cstdlib>
#include<set>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#define N 100010
#define Mod 10000007
#define lson l,mid,idx<<1
#define rson mid+1,r,idx<<1|1
#define lc idx<<1
#define rc idx<<1|1
const double EPS = 1e-11;
const double PI = acos(-1.0);
const double E=2.718281828;
typedef long long ll;
const int INF=1000010;
using namespace std;
int mp[102];///记录每一行状态,例:HPPH 用 1001 表示,mp[i]则记录mp[i]=9=2^3+2^0;
int sum[103],cnt[102];///sum记录的是每种情况1的个数,cnt则是记录对应的值
int n,m,len,dp[110][110][110];
bool ok(int x)///判断x的情况是否存在冲突,即左右一位和两位有没有1的重叠
{
if((x&(x<<1))||(x&(x<<2)))
return 0;
return 1;
}
int getsum(int x)///符合条件的x,计算1的个数
{
int ans=0;
while(x>0)
{
if(x&1)///最后一位是1的时候
ans++;
x>>=1;///左移一位,即判断下一位是否为一
}
return ans;
}
void finds()///预处理0~2^m的所有情况
{
memset(cnt,0,sizeof cnt);
len=0;
for(int i=0; i<(1<<m); i++)///i枚举所有m位的二进制数
{
if(ok(i))
{
sum[len]=getsum(i);
cnt[len++]=i;
}
}
}
int main()
{
//freopen("in.txt","r",stdin);
while(cin>>n>>m)
{
char c;
getchar();
for(int i=0; i<n; i++)
{
for(int j=0; j<m; j++)
{
scanf("%c",&c);
if(c=='H')
mp[i]|=(1<<j);///高地
}
getchar();
}
finds();
memset(dp,-1,sizeof dp);
for(int i=0; i<len; i++)///先处理第一行
{
if(!(cnt[i]&mp[0]))
dp[0][i][0]=sum[i];
}
///接下来是递推过程
for(int i=1; i<n; i++)
{
for(int j=0; j<len; j++)
{
if(mp[i]&cnt[j])
continue;
for(int ii=0; ii<len; ii++) //i-1行
{
if(cnt[j]&cnt[ii])continue;
for(int jj=0; jj<len; jj++) //i-2行
{
if(cnt[jj]&cnt[j])continue;
if(cnt[jj]&cnt[ii])continue;
if(dp[i-1][ii][jj]==-1)continue;
dp[i][j][ii]=max(dp[i][j][ii],dp[i-1][ii][jj]+sum[j]);
}
}
}
}
int ans=0;
for(int i=0; i<len; i++)
for(int j=0; j<len; j++)
if(ans<dp[n-1][i][j])
ans=dp[n-1][i][j];
cout<<ans<<endl;
}
return 0;
}
原文地址:http://blog.csdn.net/acm_baihuzi/article/details/40787499