• 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 }
  • 相关阅读:
    UVA 408 (13.07.28)
    linux概念之用户,组及权限
    Java实现 蓝桥杯 历届试题 网络寻路
    Java实现 蓝桥杯 历届试题 约数倍数选卡片
    Java实现 蓝桥杯 历届试题 约数倍数选卡片
    Java实现 蓝桥杯 历届试题 约数倍数选卡片
    Java实现 蓝桥杯 历届试题 约数倍数选卡片
    Java实现 蓝桥杯 历届试题 约数倍数选卡片
    Java实现 蓝桥杯 历届试题 九宫重排
    Java实现 蓝桥杯 历届试题 九宫重排
  • 原文地址:https://www.cnblogs.com/kickit/p/8859312.html
Copyright © 2020-2023  润新知