唔,想到了状压之后就不会了……实在是菜

考虑压两行,设$f_{i, j, k}$表示当前到第$i$行,上一行是$j$状态,前一行是$k$状态的最多能放的炮兵的数量。

发现第一维还可以滚掉,好像可以转移了。

但是,这样子$100 * 1024 * 1024 * 1024$时间炸了……怎么办?

考虑先不考虑题目中给出的不能放的格子的贡献,预处理出所有可行解,根据互不侵犯的套路,对于一个状态$i$,在这题中只要满足$i \& (i >> 1)$、$i \& (i >> 2)$、$i \& (i  << 1)$、$i \& (i << 2)$全部都是$0$,那么就是一个合法状态了吧。

对于一个合法状态(记编号为$i$),只要计算出有多少个$1$就相当于可以放多少个炮兵了吧,记这个数量为$num_i$。

一行最多才$10$列,一个炮兵可以打$5$格,发现预处理之后只有$60$来个有效状态了(状态数记为$tot$),$O(ntot^3)$可以承受了。

写一下转移方程:

    $f_{1, i, 0} = num_i$。

    $f_{2, i, j} = max(f_{1, j, 0} + num_i)$  $i, j$不冲突且$i$和第二行的地图不冲突。

    $f_{i, j, k} = max(f_{i - 1, k, t} + num_j)$  $j,k$ 、$k, t$、$j, t$不冲突且$j$和第$i$行的地图不冲突。

答案  $ans = max(f_{n, i, j})$。

注意第二行要分开处理。

时间复杂度$O(ntot^3)$,约为$O(n^4)$。

以后要记得复习!

Code:

#include <cstdio>
#include <cstring>
using namespace std; const int N = ; int n, m, a[N], tot = , b[N], num[N], f[N][N][N]; inline void chkMax(int &x, int y) {
if(y > x) x = y;
} inline int bitCnt(int now) {
int res = ;
for(; now > ; now >>= )
res += (now & );
return res;
} int main() {
scanf("%d%d", &n, &m);
for(int i = ; i <= n; i++) {
char str[];
scanf("%s", str + );
for(int j = ; j <= m; j++)
if(str[j] == 'H') a[i] |= ( << (j - ));
} for(int i = ; i < ( << m); i++)
if(!(i & (i << )) && !(i & (i << )) && !(i & (i >> )) && !(i & (i >> ))) {
++tot;
b[tot] = i, num[tot] = bitCnt(i);
if(!(a[] & b[tot])) f[][tot][] = num[tot];
} for(int i = ; i <= tot; i++)
for(int j = ; j <= tot; j++)
if(!(a[] & b[j]) && !(b[i] & b[j]))
chkMax(f[][j][i], f[][i][] + num[j]); for(int i = ; i <= n; i++)
for(int j = ; j <= tot; j++) {
if(a[i] & b[j]) continue;
for(int k = ; k <= tot; k++) {
if(b[j] & b[k]) continue;
for(int t = ; t <= tot; t++) {
if((b[k] & b[t]) || (b[t] & b[j])) continue;
chkMax(f[i][j][k], f[i - ][k][t] + num[j]);
}
}
} int ans = ;
for(int i = ; i <= tot; i++)
for(int j = ; j <= tot; j++)
chkMax(ans, f[n][i][j]); printf("%d\n", ans);
return ;
}

Luogu 2704 [NOI2001]炮兵阵地的更多相关文章

  1. 洛谷2704 [NOI2001]炮兵阵地

    题目戳这里 Solution 状压DP很好的入门题,用熟练位运算貌似也没那么难. 首先分析一下题目: 看见n=100,m=10,立马就想到了状压,看起来也像DP,所以我们还是采用行号为阶段的状压DP. ...

  2. luogu P2704 [NOI2001]炮兵阵地

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

  3. 状压dp:luogu P2704 [NOI2001]炮兵阵地

    https://www.luogu.org/problemnew/show/P2704 知识点:1.滚动数组:取模实现 2.位运算优先级最低 顾是if(!(a&b))而不是if(!a& ...

  4. [洛谷P2704] [NOI2001]炮兵阵地

    洛谷题目链接:[NOI2001]炮兵阵地 题目描述 司令部的将军们打算在NM的网格地图上部署他们的炮兵部队.一个NM的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示), ...

  5. C++ 洛谷 P2704 [NOI2001]炮兵阵地

    P2704 [NOI2001]炮兵阵地 没学状压DP的看一下 此题意思很简单,如下图,就是十字架上的不能有两个点放炮兵. 在做此题前,先做一下玉米田 玉米田题解 分析: 而m即一行的个数小于等于10, ...

  6. P2704 [NOI2001]炮兵阵地 (状压DP)

    题目: P2704 [NOI2001]炮兵阵地 解析: 和互不侵犯一样 就是多了一格 用\(f[i][j][k]\)表示第i行,上一行状态为\(j\),上上行状态为\(k\)的最多的可以放的炮兵 发现 ...

  7. 洛谷P2704 [NOI2001]炮兵阵地 [状压DP]

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

  8. [Poj1185][Noi2001]炮兵阵地(状压dp)

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

  9. NOI2001 炮兵阵地 洛谷2704

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

随机推荐

  1. 剑指offer-第六章面试中的各项能力(n个骰子的点数)

    题目:把n个骰子扔到地上,骰子之和为S,输入n,打印s所有可能的值出现的概率. 思路:由于骰子的点数为1~6,因此n个骰子之和的大小为n~6n之间.故可以定义一个数组来存放这6n-n+1个数出现的次数 ...

  2. 利用DAC(Data-tier Application)实现数据库结构迁移

    从一个存在的库,抽取其表结构,对象,权限等,再部署成一个不包含数据的"空库"的方法有很多种.如自带的Generate Scripts功能,自定义脚本提取创建脚本等. 在实际使用中, ...

  3. Spring IOC容器的初始化-(二)BeanDefinition的载入和解析

    前言 1.在讲BeanDefinition的载入和解析之前,我们先来看看什么是BeanDefinition. Bean对象在Spring中是以BeanDefinition来描述的,也就是说在Sprin ...

  4. minio  nginx 配置

    1. 参考配置  server { listen 80; server_name example.com; location / { proxy_set_header Host $http_host; ...

  5. C# 实现程序只启动一次(实现程序自重启)

    程序运行过程中,不能有多个实例运行,并且需要程序自己可以重启(重新运行),所以代码如果下代码: static void Main() { bool createNew; using (System.T ...

  6. Ubantu下安装FTP服务器

    在Linux中ftp服务器的全名叫 vsftpd,我们需要利用相关命令来开启安装ftp服务器,然后再在vsftpd.conf中进行相关配置,下面我来介绍在Ubuntu中vsftpd安装与配置增加用户的 ...

  7. CentOS6安装vsftpd

    练习:完成vsftpd配置 (1) 禁锢系统用户于家目录 [root@node3 ~]# yum -y install vsftpd [root@node3 ~]# vim /etc/vsftpd/v ...

  8. Office 2019 2016 安装破解教程

    声明:工具由蓝点网提供支持,密钥为本人收集内容,非转载部分 GVLKs for Office 2019     Product GVLK Office Professional Plus 2019  ...

  9. java调用python

    本文记录下使用jython包来实现java代码中调用Python. 一.Maven加入 <dependency> <groupId>org.python</groupId ...

  10. 作业1开发一个简单的python计算器

    开发一个简单的python计算器 实现加减乘除及拓号优先级解析 用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568 ...