zoukankan      html  css  js  c++  java
  • 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
    ",ans);
    95     }
    96     return 0;
    97 }
  • 相关阅读:
    又见博弈
    两道来自CF的题
    温习及回顾
    笔试面试总结
    Python Cha4
    初学ObjectiveC
    设计模式汇总(三)
    转贴XML的写法建议
    让从Objec中继承的类也拥有鼠标事件
    关于异常处理的一些看法
  • 原文地址:https://www.cnblogs.com/kickit/p/8859312.html
Copyright © 2011-2022 走看看