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