OJ-Problems-Source/POJ/1185.cpp
2016-08-03 15:50:31 +08:00

155 lines
3.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
#define _BITMOVE(x) (1<<x)
#define _BITMAX(x) _BITMOVE(x)
#define _BITMAXVALUE(x) (_BITMAX(x)-1)
#define MAXLINE 105
#define MAXSTATUS _BITMAX(12)
#define ESTIMATED_MAXSTATUS 129+1
typedef unsigned long STATE;
STATE map[MAXLINE];
int dp[MAXLINE][ESTIMATED_MAXSTATUS][ESTIMATED_MAXSTATUS];
STATE availableStatus[ESTIMATED_MAXSTATUS];
int countOfOne[ESTIMATED_MAXSTATUS];
char _tmpbuff[8];
inline bool isGoodState(STATE x)
{
if(x&(x<<1)) return false;
if(x&(x<<2)) return false;
return true;
}
inline STATE PlaceOnMap(int line,int stateid)
{
return map[line]&availableStatus[stateid];
}
inline STATE CheckBetweenLines(int line1,int line2)
{
return availableStatus[line1]&availableStatus[line2];
}
inline int getCountOfOneByState(STATE x)
{
int c=0;
while(x>0)
{
if(x&1) ++c;
x=x>>1;
}
return c;
}
int solve(int n,int m)
{
memset(dp,-1,sizeof(int)*MAXLINE*ESTIMATED_MAXSTATUS*ESTIMATED_MAXSTATUS);
memset(map,0,sizeof(STATE)*MAXLINE);
for(int i=0;i<n;i++)
{
gets(_tmpbuff);
for(int j=0;j<m;j++)
{
int tmp=(_tmpbuff[j]=='P')?0:1;
map[i]=(map[i]<<1)|tmp;
}
}
if(n==1&&m==1)
{
if(map[0]>0) printf("0\n");
else printf("1\n");
return 0;
}
int statusCount=-1;
for(STATE ci=0;ci<(STATE)_BITMAX(m);ci++)
{
if(isGoodState(ci))
{
availableStatus[++statusCount]=ci;
countOfOne[statusCount]=getCountOfOneByState(ci);
}
}
++statusCount;
/// Initialize the Line 0 with all available status.
for(int ci=0;ci<statusCount;ci++)
{
if(!PlaceOnMap(0,ci))
{
dp[0][ci][0]=countOfOne[ci];
}
}
/// Main DP
for(int i=1;i<n;i++)
{
for(int j=0;j<statusCount;j++)
{
if(PlaceOnMap(i,j)) continue;
/// Last Line
for(int k=0;k<statusCount;k++)
{
if(CheckBetweenLines(j,k)) continue;
/// Last Last Line
for(int x=0;x<statusCount;x++)
{
if(CheckBetweenLines(k,x)) continue;
if(CheckBetweenLines(j,x)) continue;
if(dp[i-1][k][x]==-1) continue;
dp[i][j][k]=max(dp[i][j][k],dp[i-1][k][x]+countOfOne[j]);
}
}
}
}
/// Calculate the answer
int ans=-1;
for(int ci=0;ci<statusCount;ci++)
{
for(int cj=0;cj<statusCount;cj++)
{
///此处是max运算,因为结果要求最大值
ans=max(ans,dp[n-1][ci][cj]);
}
}
printf("%d\n",ans);
return 0;
}
int main()
{
/**
/// A Program To Estimate the max value of statusCount
/// The answer is 129
int statusCount=-1;
for(STATE ci=0;ci<MAXSTATUS;ci++)
{
if(isGoodState(ci))
{
availableStatus[++statusCount]=ci;
countOfOne[statusCount]=getCountOfOneByState(ci);
}
}
++statusCount;
printf("%d\n",statusCount);
*/
int n,m;
/// %*c重要
while(scanf("%d %d%*c",&n,&m)==2)
{
solve(n,m);
}
return 0;
}