状态压缩dp 炮兵阵地

题面:

司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队。一个N*M的地图由N行M列组成,地图的每一格可能是山地(用”H” 表示),也可能是平原(用”P”表示),如下图。

在每一格平原地形上最多可以布置一支炮兵部队(山地上不能够部署炮兵部队);一支炮兵部队在地图上的攻击范围如图中黑色区域所示:

如果在地图中的灰色所标识的平原上部署一支炮兵部队,则图中的黑色的网格表示它能够攻击到的区域:沿横向左右各两格,沿纵向上下各两格。

图上其它白色网格均攻击不到。

从图上可见炮兵的攻击范围不受地形的影响。

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

输入格式

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

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

输出格式

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

数据范围

N≤100,M≤10N≤100,M≤10

输入样例:

5 4
PHPP
PPHH
PPPP
PHPP
PHHP

输出样例:

6题解:与玉米田的限制相比扩大了一倍,这里求的是最大数量。f[2][j][k]表示表示排放第i行,第i行状态为j,第i-1行状态为k的所有情况,其中i&1与i-1&1值不同所以可以作为滚动数组节省空间。同样为了节省枚举答案的步骤,则用f[n+2][0][0]表示答案;这里不同为i-2行,以此来枚举
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
vector<int>state;
int f[2][111][111];//f[i][j][k]//表示排放第i行,第i行状态为j,第i-1行状态为k的所有情况
int g[111];
int n,m;int cnt[111];
bool check(int state)
{
    for(int i=0;i<m;i++)
    {
        if((state>>i&1)&&((state>>i+1&1)||(state>>i+2&1)))//如果当前为1,后面两位有一个为1则不满足
        return false;
    }
    return true;
}
int count(int state)
{
    int res=0;
    for(int i=0;i<m;i++)
    if(state>>i&1)res++;
    return res;

}
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
     for(int j=0;j<m;j++)
     {
         char c;
         cin>>c;
         if(c==‘H‘)g[i]+=1<<j;
     }
     for(int i=0;i< 1<<m;i++)
      if(check(i))
      {
      state.push_back(i);
      cnt[i]=count(i);
      }
      for(int i=1;i<=n+2;i++)
       for(int j=0;j<state.size();j++)
        for(int k=0;k<state.size();k++)
         for(int u=0;u<state.size();u++) //对于每一种情况第i行,i-1行都一样,以第i-2行为不同划分;j表示第i-1行,k表示第i行,u表示第i-2行
         {
             int a=state[j],b=state[k],c=state[u];
             if((a&b)|(a&c)|(b&c))continue;//如果连续三行存在两个1则不满足;
             if((g[i-1]&a)|(g[i]&b))continue;//如果山地放了炮则不符合;
             f[i&1][k][j]=max(f[i&1][k][j],f[i-1&1][j][u]+cnt[b]);
         }
         cout<<f[n+2&1][0][0]<<endl;
    return 0;
}

  



原文地址:https://www.cnblogs.com/flyljz/p/12210776.html

时间: 2024-08-29 15:25:52

状态压缩dp 炮兵阵地的相关文章

状态压缩动态规划 -- 炮兵阵地

司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队,一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原(用"P"表示),如下图.在每一格平原地形上最多可以布置一支炮兵部队(山地上不能够部署炮兵部队):一支炮兵部队在地图上的攻击范围如图中黑色区域所示: 如果在地图中的灰色所标识的平原上部署一支炮兵部队,则图中的黑色的网格表示它能够攻击到的区域:沿横向左右各两格,沿纵向上下各两格.图上其它白色网格均攻击不到.从图上可见炮兵的攻击

poj 1185 炮兵阵地(状态压缩dp)

Description 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原(用"P"表示),如下图.在每一格平原地形上最多可以布置一支炮兵部队(山地上不能够部署炮兵部队):一支炮兵部队在地图上的攻击范围如图中黑色区域所示: 如果在地图中的灰色所标识的平原上部署一支炮兵部队,则图中的黑色的网格表示它能够攻击到的区域:沿横向左右各两格,沿纵向上下各两格.图上其它白色网格均攻击不

poj1185炮兵布阵结题报告--初步了解--状态压缩dp

好吧,借助poj1185炮兵布阵这题,仔仔细细的了解了一下状态压缩动态规划 首先,借助题目,我们来看看状态压缩是个虾米东西..Ok follow me 一,所谓状态压缩 根据题意,我们得在长度为M 的地图上放置一些大炮(后面简称"放炮",应该不会被和谐吧),那么,首先不考虑山地,我们得把所有的放置方法都找出来,并且注意,这里只对于一行且长度为M(好吧,你可能要问考虑一行,左右互相隔2,互相不在攻击范围,那么上下呢?这里先不急,一步步来) 1,找出所有放炮的方法 假设长度为7,那么看下图

初步了解--状态压缩dp---poj1185炮兵布阵结题报告

好吧,借助poj1185炮兵布阵这题,仔仔细细的了解了一下状态压缩动态规划 首先,借助题目,我们来看看状态压缩是个虾米东西..Ok follow me 一,所谓状态压缩 根据题意,我们得在长度为M 的地图上放置一些大炮(后面简称"放炮",应该不会被和谐吧),那么,首先不考虑山地,我们得把所有的放置方法都找出来,并且注意,这里只对于一行且长度为M(好吧,你可能要问考虑一行,左右互相隔2,互相不在攻击范围,那么上下呢?这里先不急,一步步来) 1,找出所有放炮的方法 假设长度为7,那么看下图

POJ 3254 Corn Fields 状态压缩DP (C++/Java)

http://poj.org/problem?id=3254 题目大意: 一个农民有n行m列的地方,每个格子用1代表可以种草地,而0不可以.放牛只能在有草地的,但是相邻的草地不能同时放牛, 问总共有多少种方法. 思路: 状态压缩的DP. 可以用二进制数字来表示放牧情况并判断该状态是否满足条件. 这题的限制条件有两个: 1.草地限制. 2.相邻限制. 对于草地限制,因为输入的时候1是可以种草地的. 以"11110"草地分析,就只有最后一个是不可以种草的.取反后得00001  .(为啥取反

HDU1565(状态压缩dp)

方格取数(1) Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 8170    Accepted Submission(s): 3095 Problem Description 给你一个n*n的格子的棋盘,每个格子里面有一个非负数.从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数

HDU 3001【状态压缩DP】

题意: 给n个点m条无向边. 要求每个点最多走两次,要访问所有的点给出要求路线中边的权值总和最小. 思路: 三进制状态压缩DP,0代表走了0次,1,2类推. 第一次弄三进制状态压缩DP,感觉重点是对数据的预处理,利用数组分解各个位数,从而达到类似二进制的目的. 然后就是状态的表示,dp[s][i]表示状态s时到达i的最优值. 状态转移也一目了然,不废话. #include<stdio.h> #include<string.h> #include<algorithm> u

Victor and World(spfa+状态压缩dp)

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5418 Victor and World Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/131072 K (Java/Others)Total Submission(s): 958    Accepted Submission(s): 431 Problem Description After trying hard fo

poj 3311 Hie with the Pie(状态压缩dp)

Description The Pizazz Pizzeria prides itself in delivering pizzas to its customers as fast as possible. Unfortunately, due to cutbacks, they can afford to hire only one driver to do the deliveries. He will wait for 1 or more (up to 10) orders to be