1. #include <iostream>
  2. #include <cstdio>
  3. #include <cmath>
  4. #include <algorithm>
  5. #include <string.h>
  6. #include <string>
  7.  
  8. using namespace std;
  9.  
  10. const int MAXN = 100 + 1; //阵地行数
  11. const int MAXM = 10 + 1; //阵地列数
  12. const int State_Num = 60 + 1; //阵地列状态的压缩总数,合法状态总数最多60
  13.  
  14. int dp[MAXN][State_Num][State_Num], cur[MAXN], state[State_Num], tot;
  15. char field[MAXN][MAXM]; //储存阵地
  16. int n, m; //阵地规模
  17.  
  18. /*
  19. 因为n <= 100, m <= 10,将阵地的列压缩。
  20. dp[i][j][k]表示当第i行布置结束后,第i行的布置状态为j的情况下,
  21. 第i - 1行的状态为k,所能布置的最多的炮兵。
  22.  
  23. 依据题意,我们能够删除一些状态。
  24. 删除的状态有:
  25. 1.山地不能布置炮兵
  26. 2.炮兵不能在垂直和水平的线上两格相邻。
  27. cur[]数组用于储存输入的合法局面
  28. state[]数组用于储存相邻的合法局面
  29. */
  30.  
  31. bool ok(int x)
  32. {
  33. return !((x & (x << 1)) || (x & (x << 2)));
  34. }
  35.  
  36. void init() //保留不两格相邻的
  37. {
  38. int limit = (1 << m);
  39. tot = 0;
  40.  
  41. for (int i = 0; i < limit; i++)
  42. {
  43. if (ok(i)) state[tot++] = i;
  44. }
  45. }
  46.  
  47. bool yes(int x, int i)
  48. {
  49. return !(x & cur[i]);
  50. }
  51.  
  52. int cal(int x)
  53. {
  54. int res = 0;
  55. while (x)
  56. {
  57. if (x & 1) res++;
  58. x >>= 1;
  59. }
  60. return res;
  61. }
  62.  
  63. void input()
  64. {
  65. while (scanf("%d %d", &n, &m) != EOF) //输入
  66. {
  67. init();
  68. memset(dp, 0, sizeof(dp));
  69.  
  70. for (int i = 0; i < n; i++)
  71. {
  72. scanf("%s", field[i]), cur[i] = 0;
  73. for (int j = 0; j < m; j++)
  74. if (field[i][j] == 'H') cur[i] += (1 << (m - j - 1)); //用于推断状态是否合法(1)
  75. }
  76.  
  77. for (int i = 0; i < tot; i++) //初始化第一行
  78. {
  79. if (!yes(state[i], 0)) continue;
  80. for (int j = 0; j < tot; j++)
  81. {
  82. dp[0][i][j] = cal(state[i]);
  83. }
  84. }
  85.  
  86. for (int i = 1; i < n; i++) //计算当前行,枚举上两行的状态
  87. {
  88. for (int j = 0; j < tot; j++) //枚举当前行的状态
  89. {
  90. if (!yes(state[j], i)) continue;
  91. for (int k = 0; k < tot; k++)
  92. {
  93. if (!yes(state[k], i - 1)) continue;
  94. for (int l = 0; l < tot; l++)
  95. {
  96. if (!yes(state[l], i - 2)) continue;
  97. if (((state[j] & state[k]) == 0) && ((state[j] & state[l]) == 0) && ((state[k] & state[l]) == 0))
  98. {
  99. dp[i][j][k] = max(dp[i][j][k], dp[i - 1][k][l] + cal(state[j]));
  100. }
  101. }
  102. }
  103. }
  104. }
  105.  
  106. int ans = 0; //计算答案
  107.  
  108. for (int i = 0; i < tot; i++)
  109. for (int j = 0; j < tot; j++)
  110. ans = max(ans, dp[n - 1][i][j]);
  111.  
  112. cout << ans << endl;
  113. }
  114. }
  115.  
  116. int main()
  117. {
  118. input();
  119. return 0;
  120. }

poj1185炮兵阵地的更多相关文章

  1. [poj1185]炮兵阵地_状压dp

    炮兵阵地 poj-1185 题目大意:给出n列m行,在其中添加炮兵,问最多能加的炮兵数. 注释:n<=100,m<=10.然后只能在平原的地方建立炮兵. 想法:第2到状压dp,++.这题显 ...

  2. POJ1185炮兵阵地【动态规划】

    炮兵阵地 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 26892   Accepted: 10396 Descriptio ...

  3. poj1185 炮兵阵地【状压DP】

    炮兵阵地 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 32802   Accepted: 12650 Descriptio ...

  4. POJ1185 炮兵阵地 —— 状压DP

    题目链接:http://poj.org/problem?id=1185 炮兵阵地 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions ...

  5. POJ1185 炮兵阵地 和 POJ2411 Mondriaan's Dream

    炮兵阵地 Language:Default 炮兵阵地 Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 34008 Accepted ...

  6. POJ1185 炮兵阵地

    题目描述 Description 司令部的将军们打算在N × M的网格地图上部署他们的炮兵部队.一个N × M的地图由N行M列组成,地图的每一格可能是山地(用"H"表示),也可能是 ...

  7. POJ1185 - 炮兵阵地(状态压缩DP)

    题目大意 中文的..直接搬过来... 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平 ...

  8. POJ1185 炮兵阵地 状态压缩

    因为不知道不同的博客怎么转,就把别人的复制过来了,这个题解写的非常好,原地址为: http://hi.baidu.com/wangxustf/item/9138f80ce2292b8903ce1bc7 ...

  9. poj1185炮兵阵地 正确代码及错误代码分析

    Solution:状态压缩 因为设置炮兵的局限性(同行两炮兵相差要大于2),一行10个数最多有60种可能性(程序计算) 其中判断可能性的好方法是: if ((i & (i << 1 ...

随机推荐

  1. TCP_NODELAY详解

    在网络拥塞控制领域,我们知道有一个非常有名的算法叫做Nagle算法(Nagle algorithm),这是使用它的发明人John Nagle的名字来命名的,John Nagle在1984年首次用这个算 ...

  2. 强算KMeans聚类算法演示器

    这些天做C#实验以及这个KMeans算法演示器,学了一下openGL,感觉有待加强. //Point.h /* Point 结构体定义及实现 结构体重载了2个运算符: 1.== //推断两个Point ...

  3. c/c++使用VS2013连接MySQL与ubuntu下c链接mysql

    vs连接数据库事实上就是将mysql数据库.h头文件接口.lib链接文件和dll运行文件增加到项目中.以下是配置怎样增加. 转于http://www.cnblogs.com/justinzhang/a ...

  4. 王垠:Lisp 已死,Lisp 万岁!

    王垠:Lisp 已死,Lisp 万岁!_IT新闻_博客园 王垠:Lisp 已死,Lisp 万岁!

  5. 关于java中的事件类型

    java中的Date是为了证明:天才的程序员也会犯错: java中的Calendar是为了证明:普通的程序员也会犯错. ———————————————————— stackoverflow上大部分都推 ...

  6. AdaBoost中利用Haar特征进行人脸识别算法分析与总结1——Haar特征与积分图

    原地址:http://blog.csdn.net/watkinsong/article/details/7631241 目前因为做人脸识别的一个小项目,用到了AdaBoost的人脸识别算法,因为在网上 ...

  7. VCL改变主窗体的方法

    使用如下语句即可Pointer((@Application.MainForm)^) := Form1; 仔细想想和Pointer((Application.MainForm)) := Form1;有什 ...

  8. jsoncpp使用

    第一个github网站下载jsoncpp最新的版本库:https://github.com/open-source-parsers/jsoncpp 点击右下角的Download ZIP进行下载 解压后 ...

  9. libevent安装总结 - jinfg2008的专栏 - 博客频道 - CSDN.NET

    libevent安装总结 - jinfg2008的专栏 - 博客频道 - CSDN.NET libevent安装总结 分类: linux 系统配置 2013-02-13 22:37 99人阅读 评论( ...

  10. 在java代码中进行px与dip(dp)、px与sp单位值的转换

        其实都是以前保存的代码,最近发现自己的资料库很混乱,索性都整理成博客,方便以后自己要用的时候快速找到. DisplayUtil.java /** * 单位转换工具 * * @author ca ...