*点击

[NOI2001] 炮兵阵地

题目

Description

司令部的将军们打算在 N×MN×M 的网格地图上部署他们的炮兵部队。

一个 N×MN×M 的地图由 NN 行 MM 列组成,地图的每一格可能是山地(用 HH 表示),也可能是平原(用 PP 表示),如下图。

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

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

图上其它白色网格均攻击不到。从图上可见炮兵的攻击范围不受地形的影响。

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

1≤N≤1001≤M≤10

Input

第一行包含两个由空格分割开的正整数,分别表示 NN 和 MM。

接下来的 NN 行,每一行含有连续的 MM 个字符,按顺序表示地图中每一行的数据。

Output

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

Sample Input

5 4
PHPP
PPHH
PPPP
PHPP
PHHP

Sample Output

6

思路

一道状压dp的题;

枚举当前行和上两行的状态,并保证炮兵不能互相攻击即可;

状态转移方程就为

dp[i][x][y]=max(dp[i][x][y],dp[i1][y][z]+sum);

x为第i行状态,y为第i1行的状态,z为第i2行状态,sum为第i行炮兵个数;

不过要注意的是m最大范围是10,三个枚举状态的循环会超时;

所以需要提前把满足条件的行预处理到一个数组,再枚举数组即可;

这样每个循环次数可以降到1<<6次以下,是不会超时的;

 


 

代码

复制代码
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
ll n,m;
ll tot;
ll a[1<<10],c[101][11];
ll dp[101][1<<6][1<<6];
int main()
{
    scanf("%lld%lld",&n,&m);
    for(ll i=1;i<=n;i++)
    for(ll j=1;j<=m;j++)
    {
        char cc;
        cin>>cc;
        if(cc=='P')
            c[i][j]=1;
    }
    for(ll x=0;x<=(1<<m)-1;x++)
    {
        if(x&(x<<1)||x&(x<<2))
            continue;
        a[++tot]=x;//预处理满足条件的行
    }
    for(ll i=1;i<=n;i++)
    for(ll x=1;x<=tot;x++)
    {
        ll flag=0;
        for(ll j=1;j<=m;j++)
        if(c[i][j]==0&&a[x]&(1<<(j-1)))//如果是山地,就不能放炮兵
        {
            flag=1;
            break;
        }
        if(flag) continue;
        ll sum=0;
        for(ll j=1;j<=m;j++)
        if(a[x]&(1<<(j-1)))
            sum++;//记录当前行炮兵数量
        for(ll y=1;y<=tot;y++)
        for(ll z=1;z<=tot;z++)
        {
            if(a[x]&a[y]||a[x]&a[z]) continue;//保证与上两行互不攻击
            dp[i][x][y]=max(dp[i][x][y],dp[i-1][y][z]+sum);//求最大数量
        }
    }
    ll ans=0;
    for(ll x=1;x<=tot;x++)
    for(ll y=1;y<=tot;y++)
        ans=max(ans,dp[n][x][y]);
    printf("%lld",ans);
    return 0;
}
复制代码

 

 

 

 

 

 

 

 



如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
posted @   木偶人-怪咖  阅读(17)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
*访客位置3D地图 *目录
点击右上角即可分享
微信分享提示