题意:

                 郑厂长系列故事——排兵布阵

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)

Total Submission(s): 1883    Accepted Submission(s): 686

Problem Description

  郑厂长不是正厂长

  也不是副厂长

  他根本就不是厂长

  事实上

  他是带兵打仗的团长

  一天,郑厂长带着他的军队来到了一个n*m的平原准备布阵。

  根据以往的战斗经验,每个士兵可以攻击到并且只能攻击到与之曼哈顿距离为2的位置以及士兵本身所在的位置。当然,一个士兵不能站在另外一个士兵所能攻击到的位置,同时因为地形的原因平原上也不是每一个位置都可以安排士兵。

  现在,已知n,m 以及平原阵地的具体地形,请你帮助郑厂长计算该阵地,最多能安排多少个士兵。

 

Input

输入包含多组测试数据;

每组数据的第一行包含2个整数n和m (n <= 100, m <= 10 ),之间用空格隔开;

接下来的n行,每行m个数,表示n*m的矩形阵地,其中1表示该位置可以安排士兵,0表示该地形不允许安排士兵。

 

Output

请为每组数据计算并输出最多能安排的士兵数量,每组数据输出一行。

 

Sample Input

6 6

0 0 0 0 0 0

0 0 0 0 0 0

0 0 1 1 0 0

0 0 0 0 0 0

0 0 0 0 0 0

0 0 0 0 0 0

 

Sample Output

2

思路:

      说好了状态压缩dp的,自己dp写着特别费劲,写了一个,结果超时了,然后果断换思路,后来感觉可以直接求最大独立集,因为不能抽象能二分图,所以如果想求独立集,那么就只剩下一个比较暴力的np问题了,就是最大团,虽说是np问题,但是可以靠一些很实用的剪纸和简单dp来优化,这个题目还是轻松的过掉了,建图的时候把不冲突的两个点连接起来,最后一遍最大团就行了。同样的还有POJ1185 炮兵阵地,只是建图的时候的限制不一样而已,别的都一样,具体看代码,明明是在学习dp,怎么又写图论了。

#include<stdio.h>

#include<string.h>

#define N 1100

typedef struct

{

   int x ,y;

}NODE;

NODE node[N];

int map[N][N] ,n;

int dp[N] ,now[N];

int Ans;

void DFS(int s ,int sum)

{

   if(Ans < sum)  Ans = sum;

   int tnow[N] ,able = 0;

   for(int i = s + 1 ;i <= n ;i ++)

   {

      tnow[i] = now[i];

      if(now[i]) able ++;

   }

   if(able + sum < Ans) return;

   for(int i = s + 1 ;i <= n ;i ++)

   {

      if(!tnow[i]) continue;

      if(sum + dp[i] <= Ans) return;

      for(int j = s+1 ;j <= n ;j ++)

      now[j] = tnow[j] & map[i][j];

      DFS(i ,sum + 1);

   }

}

int Max_Tuan()

{

   dp[n] = Ans = 1;

   for(int i = n - 1 ;i >= 1 ;i --)

   {

      for(int j = 1 ;j <= n ;j ++)

      now[j] = map[i][j];

      now[i] = 1;

      DFS(i ,1);

      dp[i] = Ans;

   }

   return Ans;

}

int abss(int x)

{

   return x > 0 ? x : -x;

}

int ok(int a ,int b)

{

   int dis = abss(node[a].x - node[b].x) + abss(node[a].y - node[b].y);

   if(dis == 2) return 0;

   return 1;

}

int main ()

{

   int nn ,mm ,i ,j ,a;

   while(~scanf("%d %d" ,&nn ,&mm))

   {

      int nowid = 0;

      for(i = 1 ;i <= nn ;i ++)

      for(j = 1 ;j <= mm ;j ++)

      {

         scanf("%d" ,&a);

         if(!a) continue;

         nowid ++;

         node[nowid].x = i ,node[nowid].y = j;

      }

      if(!nowid)

      {

         printf("0\n");

         continue;

      }

      memset(map ,0 ,sizeof(map));

      for(i = 1 ;i <= nowid ;i ++)

      for(j = i + 1 ;j <= nowid ;j ++)

      map[i][j] = map[j][i] = ok(i ,j);

      n = nowid;

      printf("%d\n" ,Max_Tuan());

   }

   return 0;

}

POJ 1185

炮兵阵地

Time Limit: 2000MS Memory Limit: 65536K

Total Submissions: 19703 Accepted: 7610

Description

司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队。一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原(用"P"表示),如下图。在每一格平原地形上最多可以布置一支炮兵部队(山地上不能够部署炮兵部队);一支炮兵部队在地图上的攻击范围如图中黑色区域所示: 

如果在地图中的灰色所标识的平原上部署一支炮兵部队,则图中的黑色的网格表示它能够攻击到的区域:沿横向左右各两格,沿纵向上下各两格。图上其它白色网格均攻击不到。从图上可见炮兵的攻击范围不受地形的影响。 

现在,将军们规划如何部署炮兵部队,在防止误伤的前提下(保证任何两支炮兵部队之间不能互相攻击,即任何一支炮兵部队都不在其他支炮兵部队的攻击范围内),在整个地图区域内最多能够摆放多少我军的炮兵部队。 

Input

第一行包含两个由空格分割开的正整数,分别表示N和M; 

接下来的N行,每一行含有连续的M个字符('P'或者'H'),中间没有空格。按顺序表示地图中每一行的数据。N <= 100;M <= 10。

Output

仅一行,包含一个整数K,表示最多能摆放的炮兵部队的数量。

Sample Input

5 4

PHPP

PPHH

PPPP

PHPP

PHHP

Sample Output

6

Source

    

#include<stdio.h>

#include<string.h>

#define N 1100

typedef struct

{

   int x ,y;

}NODE;

NODE node[N];

int map[N][N] ,n;

int dp[N] ,now[N];

int Ans;

void DFS(int s ,int sum)

{

   if(Ans < sum)  Ans = sum;

   int tnow[N] ,able = 0;

   for(int i = s + 1 ;i <= n ;i ++)

   {

      tnow[i] = now[i];

      if(now[i]) able ++;

   }

   if(able + sum < Ans) return;

   for(int i = s + 1 ;i <= n ;i ++)

   {

      if(!tnow[i]) continue;

      if(sum + dp[i] <= Ans) return;

      for(int j = s+1 ;j <= n ;j ++)

      now[j] = tnow[j] & map[i][j];

      DFS(i ,sum + 1);

   }

}

int Max_Tuan()

{

   dp[n] = Ans = 1;

   for(int i = n - 1 ;i >= 1 ;i --)

   {

      for(int j = 1 ;j <= n ;j ++)

      now[j] = map[i][j];

      now[i] = 1;

      DFS(i ,1);

      dp[i] = Ans;

   }

   return Ans;

}

int abss(int x)

{

   return x > 0 ? x : -x;

}

int ok(int a ,int b)

{

    int xx = abss(node[a].x - node[b].x);

    int yy = abss(node[a].y - node[b].y);

    if(!xx && yy <= 2 || !yy && xx <= 2) return 0;

    return 1;

}

int main ()

{

   int nn ,mm ,i ,j ,a;

   char str[110];

   while(~scanf("%d %d" ,&nn ,&mm))

   {

      int nowid = 0;

      for(i = 1 ;i <= nn ;i ++)  

      {

         scanf("%s" ,str); 

         for(j = 1 ;j <= mm ;j ++)

         {

           

            if(str[j-1] != 'P') continue;

            nowid ++;

            node[nowid].x = i ,node[nowid].y = j;

         }

      }

      if(!nowid)

      {

         printf("0\n");

         continue;

      }

      memset(map ,0 ,sizeof(map));

      for(i = 1 ;i <= nowid ;i ++)

      for(j = i + 1 ;j <= nowid ;j ++)

      map[i][j] = map[j][i] = ok(i ,j);

      n = nowid;

      printf("%d\n" ,Max_Tuan());

   }

   return 0;

}

    

    

  

      

      

         

   

      

      

hdu4539 郑厂长系列故事——排兵布阵 + POJ1158 炮兵阵地的更多相关文章

  1. HDU-4539郑厂长系列故事——排兵布阵(状态压缩,动态规划)

    郑厂长系列故事--排兵布阵 Time Limit : 10000/5000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other) Total ...

  2. 状态压缩 HDU4539 郑厂长系列故事——排兵布阵

    多组n *m 0不能放1可以放 每个士兵可以攻击到并且只能攻击到与之曼哈顿距离为2的位置以及士兵本身所在的位置. #include<stdio.h> #include<algorit ...

  3. 郑厂长系列故事——排兵布阵 hdu4539(状态压缩DP)

    郑厂长系列故事——排兵布阵 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)To ...

  4. HDU 4539郑厂长系列故事――排兵布阵(状压DP)

    HDU 4539  郑厂长系列故事――排兵布阵 基础的状压DP,首先记录先每一行可取的所哟状态(一行里互不冲突的大概160个状态), 直接套了一个4重循环居然没超时我就呵呵了 //#pragma co ...

  5. HDU 4539 郑厂长系列故事——排兵布阵

    http://acm.hdu.edu.cn/showproblem.php?pid=4539 郑厂长系列故事——排兵布阵 Time Limit: 10000/5000 MS (Java/Others) ...

  6. HDU 4539 郑厂长系列故事——排兵布阵 状压dp

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4539 郑厂长系列故事--排兵布阵 Time Limit: 10000/5000 MS (Java/O ...

  7. HDU 4539 郑厂长系列故事——排兵布阵 —— 状压DP

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4539 郑厂长系列故事——排兵布阵 Time Limit: 10000/5000 MS (Java/Ot ...

  8. POJ 1185 - 炮兵阵地 & HDU 4539 - 郑厂长系列故事——排兵布阵 - [状压DP]

    印象中这道题好像我曾经肝过,但是没肝出来,现在肝出来了也挺开心的 题目链接:http://poj.org/problem?id=1185 Time Limit: 2000MS Memory Limit ...

  9. HDU 4539 郑厂长系列故事――排兵布阵(曼哈顿距离)

    这虽然是中文题,然而没看懂,不懂的地方,就是在曼哈顿距离这块,网上搜索了一下,写了个程序,是测试曼哈顿距离的. 曼哈顿距离:两点(x1,y1)(x2,y2)的曼哈顿距离为|x1-x2|+|y1-y2| ...

随机推荐

  1. MySQL深入研究--学习总结(2)

    前言 接上文,继续学习后续章节. 第四章&第五章<深入浅出索引> 这两章节主要介绍的索引结构及其如何合理建立索引,但是我觉得讲的比较简单. 总结回顾下吧,其实在我之前的文章< ...

  2. C#扩展方法的一分钟小例子

    扩展方法是静态方法,是类的一部分,但没有在类的源代码中,就像一个补丁 首先创建一个静态类,然后创建一个静态方法,重点是静态方法的参数 public static class xExtension { ...

  3. 线上MySQL读写分离,出现写完读不到问题如何解决

    大家好,我是历小冰. 今天我们来详细了解一下主从同步延迟时读写分离发生写后读不到的问题,依次讲解问题出现的原因,解决策略以及 Sharding-jdbc.MyCat 和 MaxScale 等开源数据库 ...

  4. mybatis&plus系列------Mysql的JSON字段的读取和转换

    mybatis&plus系列------Mysql的JSON字段的读取和转换 一. 背景 在平常的开发中,我们可能会有这样的需求: 业务数据在存储的时候,并不是以mysql中的varchar丶 ...

  5. CF533F Encoding 题解

    题目链接CF533F Encoding 提示1:   \(\mathcal O(26^2*n)\) 的算法可通过.常用的几种字符串匹配算法kmp,AC自动机,哈希都可以解决该问题 (后两者可以优化到 ...

  6. LZZY高级语言程序设计之169页**5.17

    import java.util.Scanner;public class MQ3 { public static void main(String[] args) { Scanner sc = ne ...

  7. Webpack 学习笔记(1) 开始

    目录 参考资料 1. 基础设定 2. 创建一个包 3. 使用配置文件完成打包命令 4. 使用 NPM Scripts 完成打包命令 参考资料 Getting Started | Webpack web ...

  8. 在ASP.NET Core中用HttpClient(三)——发送HTTP PATCH请求

    在前面的两篇文章中,我们讨论了很多关于使用HttpClient进行CRUD操作的基础知识.如果你已经读过它们,你就知道如何使用HttpClient从API中获取数据,并使用HttpClient发送PO ...

  9. Java例题_27 100以内的素数

    1 /*27 [程序 27 求素数] 2 题目:求 100 之内的素数 3 */ 4 5 /*分析 6 * 素数:是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数. 7 * 同第二题: ...

  10. 推荐一款全能测试开发神器:Mockoon!1分钟快速上手!

    1. 说一下背景 在日常开发或者测试工作中,经常会因为下游服务不可用或者不稳定时,通过工具或者技术手段去模拟一个HTTP Server,或者模拟所需要的接口数据. 这个时候,很多人脑海里,都会想到可以 ...