[状压dp]POJ1185 炮兵阵地

中文题 题意不再赘述

对于中间这个“P” 根据dp的无后效性 我们只需考虑前面的

就变成了 只需考虑:

也就是状压前两行

具体与HDOJ的4539类似: 看HDOJ 4539

仅仅是共存状态的判断不同

 1 //#include <bits/stdc++.h>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <iostream>
 5 #include <algorithm>
 6 using namespace std;
 7 typedef long long LL;
 8 
 9 int dp[2][1050][1050], mp[105][105];
10 int pos[1050], d;
11 int main()
12 {
13     int d=0;
14     for(int i=0;i<(1<<10);i++)
15         if(!(i&(i<<2)) && !(i&(i<<1)))
16             pos[d++]=i;// 预处理 一行 符合条件的
17     int n, m;
18     while(~scanf("%d%d", &n, &m))
19     {
20         int ans=0;
21         memset(mp, 0, sizeof(mp));
22         for(int i=1;i<=n;i++)
23             for(int j=0;j<m;j++)
24             {
25                 char c;
26                 cin>>c;
27                 mp[i][j]=(c=='P');
28             }
29         memset(dp, 0, sizeof(dp));
30         for(int i=1;i<=n;i++)//枚举n行
31             for(int j=0;j<d && pos[j]<(1<<m);j++)
32             {
33                 int sum=0;
34                 for(int k=0;k<m;k++)//对于当前(i,k位置)该行(前面k格)是否满足
35                     if(pos[j]&1<<k)
36                         sum+=mp[i][k];
37                 for(int k=0;k<d && pos[k]<(1<<m);k++) // 枚举i-1行的状态 看能否与第i行共存
38                     if(!(pos[j]&pos[k]))
39                     {
40                         int tmp=0;
41                         for(int l=0;l<d && pos[l]<(1<<m);l++)  // 枚举i-2行的状态 看能否与第i行、第i-1行共存
42                             if(!(pos[j]&pos[l]))
43                                 tmp=max(tmp, dp[1-i&1][k][l]);
44                         dp[i&1][j][k]=tmp+sum;
45                         ans=max(ans, dp[i&1][j][k]);
46                     }
47             }
48         printf("%d
", ans);
49     }
50     return 0;
51 }
POJ 1185
原文地址:https://www.cnblogs.com/Empress/p/4338893.html