poj 1185 炮兵阵地

链接:点我

又是去年的题,拿到就忘了

 1 #include <cstdio>
 2 #include <cstring>
 3 using namespace std;
 4 #define max(a,b) (a) > (b) ? (a) : (b)
 5  
 6 int N,M;
 7 char map[110][20],num[110],top;
 8 int stk[70],cur[110];
 9 int dp[110][70][70];
10  
11 inline bool ok(int x){  //判断该状态是否合法,即不存在相邻的1之间的距离小于3的
12    if(x&(x<<1)) return 0;
13    if(x&(x<<2)) return 0;
14    return 1;
15 }
16 //找到所有可能的合法状态,最多60种
17 inline void jinit()
18 {
19    top=0;
20    int i,total=1<<N;
21    for(i=0;i<total;i++) if(ok(i)) stk[++top]=i;
22 }
23 //判断状态x是否与第k行匹配
24 inline bool fit(int x,int k)
25 {
26    if(cur[k]&x) return 0;
27    return 1;
28 }
29 //数一个整型数x的二进制中1的个数(用于初始化)
30 inline int jcount(int x)
31 {
32    int cnt=0;
33    while(x)
34    {
35        cnt++;
36        x&=(x-1);
37    }
38    return cnt;
39 }
40  
41 int main(){
42    while(scanf("%d%d",&M,&N) != EOF){
43        if(N == 0 && M == 0)break;
44        jinit();
45        for(int i = 1; i <= M; ++i)scanf("%s",map[i]+1);
46        for(int i = 1; i <= M; ++i)
47        for(int j = 1; j <= N; ++j){
48            cur[i]=0;
49            for(j=1;j<=N;j++){
50                 if(map[i][j]=='H')cur[i]+=(1<<(j-1));
51            }
52        }
53        memset(dp,-1,sizeof(dp));
54  
55        //初始化第一行状态
56        for(int i = 1;i <= top;i++){
57            num[i]=jcount(stk[i]);
58            if(fit(stk[i],1))
59                 dp[1][1][i]=num[i];
60        }
61        int i,t,j,k;
62        for(i = 2;i <= M;i++){
63            for(t = 1;t <= top;t++){
64                 if(!fit(stk[t],i)) continue;
65                 for(j = 1;j <= top;j++)
66                 {
67                     if(stk[t]&stk[j])continue;
68                     for(k = 1;k <= top;k++)
69                     {
70                         if(stk[t]&stk[k])continue;
71                         if(dp[i-1][j][k]==-1)continue;
72                         dp[i][k][t] =max(dp[i][k][t],dp[i-1][j][k]+num[t]);
73                     }
74                 }
75            }
76        }
77        int ans = 0;
78        for(j = 1; j <= top; ++j)
79        for(k = 1; k <= top; ++k)
80        ans = max(ans,dp[M][j][k]);
81        printf("%d
",ans);
82    }
83    return 0;
84 }
原文地址:https://www.cnblogs.com/cnblogs321114287/p/4502391.html