[NOI2001] 炮兵阵地 (状压Dp经典例题)
如果您的电脑比较优秀能在 1sec 内跑过 2^1000 的时间复杂度,不妨你可以尝试一下,其实实际时间复杂度远远少于 2^1000,作为骗分不错的选择QAQ,然后我们来分析一下正解:
很显然此题是一题裸的状压Dp,一看数据范围就知道了,所以状态变得很显然了 f[i][j][k] 表示到第 i 层前一层是 j 上上层是 k 的最大炮兵数。
所以转移就很显然:f[i][j][k]=max{f[i-1][k][q]+Num[j]} (Num[j] 表示第 j 行的炮兵数)
显然时间复杂度变为了O(n*4^m*2^m),如果评测机优秀凭借你完美的常数系统应该可以卡过,但实际上真的需要枚举 2^n 个状态嘛,显然是不需要,所以我们只需要枚举一些合法状态就可以了,令人惊讶的是每一层的合法状态竟然只有60种,所以我们的时间复杂度达到了优秀的 O(n*60^3),舒服QWQ!!!
所以我们状态变为了:f[i][j][k] 表示第 i 行前一行是合法状态 j 上上行为合法状态 k 的最大炮兵数。
转移同上咯,自行领悟。(注意需要判断当前的合法状态是否符合当前的地形)。
随后附上我的完美代码QWQ:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
const int MAXN=; int Map[MAXN], Plan[MAXN], Num[MAXN], dp[MAXN][MAXN][MAXN];
int N, m, cnt=, ans; inline int get_one(int i){
int sum=;
for (int x=i; x; x-=x & (-x)) sum++;
return sum;
} int main(){
scanf("%d%d", &N, &m);
for (int i=; i<=N; i++){
char st[];
scanf("%s", st+);
int len=strlen(st+);
for (int j=; j<=len; j++)
if (st[j]=='H') Map[i]+=(<<j-);
} //记录当前行的地形
for (int i=; i<(<<m); i++){
if ((!((i<<)&i)) && (!((i>>)&i)) && (!((i<<)&i)) && (!((i>>)&i))){
cnt++;
Plan[cnt]=i;
Num[cnt]=get_one(i); //预处理当前行有几个炮兵
if (!(Map[] & Plan[cnt])) dp[][cnt][]=Num[cnt]; //预处理第一行的状态
}
}
for (int i=; i<=cnt; i++)
for (int j=; j<=cnt; j++)
if ((!(Plan[i] & Plan[j])) && (!(Plan[j] & Map[])))
dp[][j][i]=max(dp[][i][]+Num[j], dp[][j][i]);
//预处理第二行的状态
for (int i=; i<=N; i++){
for (int j=; j<=cnt; j++)
if (!(Plan[j] & Map[i])){
for (int k=; k<=cnt; k++)
if (!(Plan[j] & Plan[k])){
for (int q=; q<=cnt; q++)
if (!(Plan[j] & Plan[q]) && !(Plan[q] & Plan[k]))
dp[i][j][k]=max(dp[i][j][k], dp[i-][k][q]+Num[j]);
}
}
}
//Dp转移
for (int i=; i<=cnt; i++)
for (int j=; j<=cnt; j++)
ans=max(ans, dp[N][i][j]);
//求最后一行的最值
printf("%d\n", ans);
return ;
}
最后比较空的小伙伴可以去尝试一下,NOIP2016D2T3 愤怒的小鸟这一题,加油加油
[NOI2001] 炮兵阵地 (状压Dp经典例题)的更多相关文章
- 洛谷P2704 [NOI2001]炮兵阵地 [状压DP]
题目传送门 炮兵阵地 题目描述 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用“H” 表示),也可能是平原(用“P”表示),如下图 ...
- P2704 [NOI2001]炮兵阵地 (状压DP)
题目: P2704 [NOI2001]炮兵阵地 解析: 和互不侵犯一样 就是多了一格 用\(f[i][j][k]\)表示第i行,上一行状态为\(j\),上上行状态为\(k\)的最多的可以放的炮兵 发现 ...
- [NOI2001]炮兵阵地 状压DP
题面: 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用“H” 表示),也可能是平原(用“P”表示),如下图.在每一格平原地形上最多 ...
- [POJ1185][NOI2001]炮兵阵地 状压DP
题目链接:http://poj.org/problem?id=1185 很裸的状压,考虑对于一行用二进制储存每一种的状态,但是状态太多了做不了. 观察到有很多状态都是不合法的,于是我们预处理出合法的状 ...
- TZOJ 4912 炮兵阵地(状压dp)
描述 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原(用"P" ...
- POJ1185 炮兵阵地 —— 状压DP
题目链接:http://poj.org/problem?id=1185 炮兵阵地 Time Limit: 2000MS Memory Limit: 65536K Total Submissions ...
- poj - 1185 炮兵阵地 状压DP 解题报告
炮兵阵地 Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 21553 Accepted: 8363 Description ...
- luogu 2704 炮兵阵地 状压dp
状压的基础题吧 第一次看感觉难上天,后来嘛就.. 套路:先根据自身状态筛出可行状态,再根据地图等其他限制条件筛选适合的状态加入答案 f i,j,k 分别代表 行数,本行状态,上行状态,再累加答案即可 ...
- POJ 1185 炮兵阵地 状压dp
题目链接: http://poj.org/problem?id=1185 炮兵阵地 Time Limit: 2000MS Memory Limit: 65536K 问题描述 司令部的将军们打算在N*M ...
随机推荐
- 跟我一起玩Win32开发(10):绘图(C)
今天我们来欣赏一下用于填充图形的函数,当然我不会逐个去介绍,因为我们参考MSDN直接套参数就可以了. SetDCBrushColor函数有必要扯一下,它的声明如下: COLORREF SetDCBru ...
- AtCoder Grand Contest 003 E - Sequential operations on Sequence
题目传送门:https://agc003.contest.atcoder.jp/tasks/agc003_e 题目大意 一串数,初始为\(1\sim N\),现有\(Q\)个操作,每次操作会把数组长度 ...
- E. Anton and Tree 数组开大点
http://codeforces.com/contest/734/problem/E 看了题解,缩点 + 树的直径. 然而一直wa14. 注意到, 缩点后重建图,在5的时候,5和6建了一条边,然后6 ...
- 分区表,磁盘概念和parted的使用
分区表,磁盘概念和parted的使用 登录陌生系统首先要做的事: 个人认为,首先得知道Linux版本的什么:cat /etc/issue df:查看磁盘的分区和数据的分配情况,类型(NFS,ext4. ...
- Myisamchk使用
Myisam损坏的情况: . 服务器突然断电导致数据文件损坏;强制关机,没有先关闭mysql 服务;mysqld 进程在写表时被杀掉.因为此时mysql可能正在刷新索引. . 磁盘损坏. . 服务器死 ...
- 动手实现 Redux(一):优雅地修改共享状态
从这节起我们开始学习 Redux,一种新型的前端“架构模式”.经常和 React.js 一并提出,你要用 React.js 基本都要伴随着 Redux 和 React.js 结合的库 React-re ...
- android开发学习 ------- RecyclerView多类型实例
实现RecyclerView多类型的实例:效果如下图所示 public class CarFragment extends Fragment{ private View view; private R ...
- Android SlidingTabLayout的使用--替代ActionBar的Tab导航
最近在使用ActionBar的时候,如果使用的是最新版V7包或者最新的SDK平台,就会发现 ActionBar的导航功能已经不建议使用了.主要的原因是ActionBar自带Tab导航自定义性差(只能通 ...
- android动画之通过子线程来实现动画
android动画之通过子线程来实现动画 使用android动画机制,往往是相对于原始位置来进行参照. 这里通过子线程修改物体位置实现动画. 布局文件: <RelativeLayout xmln ...
- Android虚拟机电池状态设置
问题描述: 安装SDK后使用AVD配合APPIUM进行测试,此时虚拟机的电池状态为0%充电中:部分APP会对手机电池状态有要求,不符合要求时,无法安装或打开. 解决思路: 1.Android系统设置( ...