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

考虑压两行,设$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. UIImage+PYJColorBecomeImage

    UIImage+PYJColorBecomeImage.h: // // UIImage+PYJColorBecomeImage.h // 颜色转成图片 // // Created by PengYu ...

  2. UITextField的使用总结

    初始化一个文字框: UITextField * textField = [[UITextField alloc]initWithFrame:CGRectMake(, , , )]; 设置和获取文字框文 ...

  3. springboot 不同环境不同的配置

    前言 我们在开发Spring Boot应用时,通常同一套程序会被应用和安装到几个不同的环境,比如:开发.测试.生产等.其中每个环境的数据库地址.服务器端口等等配置都会不同,如果在为不同环境打包时都要频 ...

  4. Yii中处理前后台登录新方法

    我一开始的做法是在后台登录时设置一个isadmin的session,然后再前台登录时注销这个session,这样做只能辨别是前台登录还是后台登录,但做不到前后台一起登录,也即前台登录了后台就退出了,后 ...

  5. HttpClient超时设置

    场景:最近并发较高,看到响应时间6s的时候,心里咯噔一下,我记得我设置的超时时间是5s啊.   原来读取超时时间没生效,只生效了连接超时时间. ConnectionPoolTimeoutExcepti ...

  6. SpringMVC集成rabbitMQ

    Maven引入相关jar <dependency> <groupId>com.rabbitmq</groupId> <artifactId>amqp-c ...

  7. vscode使用Markdown文档编写

    首先安装vscode工具,具体的使用可以参考之前的博文:<Visual Studio Code教程:基础使用和自定义设置> VScode已经默认集成markdown文档编辑插件.可以新建一 ...

  8. OpenCL™ 2.0 – Pipes

    copy from http://developer.amd.com/community/blog/2014/10/31/opencl-2-0-pipes/ OpenCL™ 2.0 – Pipes I ...

  9. ClassLoader热加载的简单实现

    当我们在eclipse中修改了一个.java文件时,并通过[ctrl + s ]保存了此java文件,相应的bin目录中,会发现.class文件也发生了修改.通常情况下,java文件是在我们的web项 ...

  10. 【转】Jmeter压力测试模拟并发

    jmeter下载地址:http://jmeter.apache.org/download_jmeter.cgi JMeterPlugins(jmeter插件):http://jmeter-plugin ...