poj 1185 炮兵阵地

题意:

中文题意,略。

思路:

一支炮兵部队可以攻击的范围是两格,所以当前行的状态只和前两行的状态有关。

所以就枚举当前行,前一行和前两行的状态,如果用二进制枚举,2^M的三次方,M最大为10,铁定TLE。

其实状态并没有想的那么多,因为隔两格才可以放一个,所以其实真的有效的状态不会超过100个。

100的三次方就可以接受。

另外,为了节省时间以及方便处理,那么可以将输入的状态压缩为2进制。

还有就是,答案最后再找吧。。。

代码:

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <algorithm>
 4 #include <vector>
 5 using namespace std;
 6 const int N = 200;
 7 int dp[105][N][N];
 8 int num[1<<12];
 9 char mp[105][N];
10 int mmp[105];
11 vector<int> g;
12 int n,m;
13 int cal(int x)
14 {
15     int cnt = 0;
16     while (x)
17     {
18         if (x&1) cnt++;
19         x >>= 1;
20     }
21     return cnt;
22 }
23 bool judge(int x)
24 {
25     if (x & (x<<1)) return 0;
26     if (x & (x<<2)) return 0;
27     return 1;
28 }
29 int main()
30 {
31     while (scanf("%d%d",&n,&m)!=EOF)
32     {
33         memset(mmp,0,sizeof(mmp));
34         memset(num,0,sizeof(num));
35         memset(dp,0,sizeof(dp));
36         g.clear();
37         for (int i = 0;i < n;i++)
38         {
39             scanf("%s",mp[i]);
40             for (int j = 0;j < m;j++)
41             {
42                 if (mp[i][j] == 'H') mmp[i] |= (1 << j);
43             }
44         }
45         for (int i = 0;i <(1<<m);i++)
46         {
47             if (judge(i)) g.push_back(i);
48             num[i] = cal(i);
49         }
50         int ans = 0;
51         for (int i = 0;i < g.size();i++)
52         {
53             if (g[i]&mmp[0]) continue;
54             dp[0][i][0] = max(dp[0][i][0],num[g[i]]);
55         }
56         for (int i = 0;i < g.size();i++)
57         {
58             for (int j = 0;j < g.size();j++)
59             {
60                 int x = g[i],y = g[j];
61                 if (x&y) continue;
62                 if (y&mmp[1]) continue;
63                 dp[1][j][i] = max(dp[1][j][i],dp[0][i][0]+num[y]);
64             }
65         }
66         for (int i = 0;i < n - 2;i++)
67         {
68             for (int j = 0;j < g.size();j++)
69             {
70                 for (int k = 0;k < g.size();k++)
71                 {
72                     for (int l = 0;l < g.size();l++)
73                     {
74                         int x = g[j],y = g[k],z = g[l];
75                         if (x&z) continue;
76                         if (x&y) continue;
77                         if (y&z) continue;
78                         if (z&mmp[i+2]) continue;
79                         dp[i+2][l][k] = max(dp[i+2][l][k],dp[i+1][k][j] + num[z]);
80                     }
81                 }
82             }
83         }
84         for (int i = 0;i < g.size();i++)
85         {
86             for (int j = 0;j < g.size();j++)
87             {
88                 int x = g[i],y = g[j];
89                 if (x&y) continue;
90                 if (mmp[n-1]&y) continue;
91                 ans = max(ans,dp[n-1][j][i]);
92             }
93         }
94         printf("%d\n",ans);
95     }
96     return 0;
97 }

 

posted @ 2018-04-16 23:47  qrfkickit  阅读(145)  评论(0编辑  收藏  举报