zoukankan      html  css  js  c++  java
  • poj 1185 炮兵阵地(三维状态压缩dP)

    题目:http://poj.org/problem?id=1185

    思路:

    d[i][j][k]表示第i行的状态为第k个状态,第i-1行的状态为第j个状态的时候 的炮的数量。

    1表示放大炮, 地形状态中1表示山地。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <algorithm>
     6 using namespace std;
     7 #define max(a, b) (a) > (b)?(a):(b)
     8 
     9 int cnt, c[80], m, n;
    10 char map[110][20], num[110];
    11 int d[110][70][70], cur[110];
    12 bool ok(int x)  //判断一行中,是否合法
    13 {
    14     if(x&(x<<1)) return false;
    15     if(x&(x<<2)) return false;
    16     return true;
    17 }
    18 void init()  //初始计算这n个 有多少种合法的状态
    19 {
    20     int i;
    21     cnt = 0;
    22     for(i = 0; i < (1<<n); i++)
    23         if(ok(i))
    24             c[++cnt] = i;
    25 }
    26 bool fit(int x, int k) //判断当前行的状态是否与 地形合法
    27 {
    28     if(cur[k]&x) return false;
    29     return true;
    30 }
    31 int cal(int x)
    32 {
    33     int sum = 0;
    34     while(x)
    35     {
    36         sum++;
    37         x = (x&(x-1)); //计算一行中1的个数,相当于每次都减去1个1
    38     }
    39     return sum;
    40 }
    41 int main()
    42 {
    43     int i, j, k, t, ans;
    44     while(~scanf("%d%d", &m, &n))
    45     {
    46         if(n==0 && m==0)
    47             break;
    48         init();
    49         for(i = 1; i <= m; i++)
    50             scanf("%s", map[i]);
    51         for(i = 1; i <= m; i++)
    52         {
    53               cur[i] = 0;
    54             for(j = 0; j < n; j++)
    55             {
    56                 if(map[i][j]=='H')
    57                 cur[i] += 1;
    58                 if(j != n-1)
    59                 cur[i] = (cur[i]<<1);
    60             }
    61         }
    62         memset(d, -1, sizeof(d));
    63 
    64         for(i = 1; i <= cnt; i++)  //初始第1行
    65         {
    66             num[i] = cal(c[i]);
    67             if(fit(c[i], 1))
    68             d[1][1][i] = num[i];
    69         }
    70         for(i = 2; i <= m; i++)
    71         for(t = 1; t <= cnt; t++)
    72         {
    73             if(!fit(c[t], i))
    74             continue;
    75             for(j = 1; j <= cnt; j++)
    76             {
    77                 if(c[t]&c[j]) continue; //判断与上上行合法
    78                 for(k = 1; k <= cnt; k++)
    79                 {
    80                     if(c[t]&c[k]) continue; //判断与上行合法
    81                     if(d[i-1][j][k]==-1) continue;
    82                     d[i][k][t] = max(d[i][k][t], d[i-1][j][k]+num[t]);
    83                 }
    84             }
    85         }
    86 
    87         ans = 0;
    88         for(i = 1; i <= m; i++)
    89         for(j = 1; j <= cnt; j++)
    90         for(k = 1; k <= cnt; k++)
    91         ans = max(ans, d[i][j][k]);
    92         printf("%d
    ", ans);
    93     }
    94     return 0;
    95 }
  • 相关阅读:
    黄聪:自己写的C#对Access操作的数据回滚程序
    黄聪:c# 操作配置文件Properties.Settings
    黄聪:C#类似MSN的右下角弹出窗体
    黄聪:C#尽量使用接口来编程
    黄聪:C#中PictureBox异步加载图片
    黄聪:C# 窗体边框阴影效果
    黄聪:C#安装程序中打包MSDE的八个步骤
    黄聪:c#水晶报表的进一步功能和使用
    黄聪:C# 窗体拖拽功能
    黄聪:C# 日期格式
  • 原文地址:https://www.cnblogs.com/bfshm/p/3587185.html
Copyright © 2011-2022 走看看