#417 Div2 Problem B Sagheer, the Hausmeister (DFS && 枚举)
题目链接:http://codeforces.com/contest/812/problem/B
题意 : 给出一个 n (1 ≤ n ≤ 15)层的教学楼, 每一层楼包含 m (1 ≤ m ≤ 100)个房间, 另外每一层的两边还有楼梯口, 接下来有n 行每行有 m+2(包含楼梯口) 用0和1来表示这栋楼的信息, 0代表这个房间的灯没亮, 1代表亮, 现在保安在整栋楼的左下角的楼梯口, 他的目的是关掉这栋楼所有的灯, 而且保安在上楼时他所在的当前楼层灯需全灭才能继续上楼, 而且每经过一个房间和上下楼梯都需要消耗1分钟, 问你最后最少需要多少分钟才能将整栋楼的灯关掉(注意灯全灭的楼层可以不必理会)!还有保安在关掉所有灯后就不会进行任何移动操作了!
分析 : 这题的关键是保安上楼时的决策, 即若保安现在左楼梯, 那他到底是关灯后下一层通过右楼梯走上上一层(这时耗时就是m+1), 还是先去关掉这一层所有的灯再走回左边楼梯上楼。由于这题楼层最多只有15层, 如果枚举每一层保安所有可能的走法那也就是2^15次方的复杂度, 可以接受, 所以可以采用DFS来枚举所有保安走法即可, 但是这里需要注意楼顶的层数并不一定是n, 因为可能在某一层例如第k层以后, 上面的灯就全都是灭的, 那保安就没必要继续上楼了, 枚举到第k层即可!
瞎想 : 可否贪心模拟?我一开始是考虑对于每一层保安所在的楼梯口进行贪心策略, 看通过哪一个楼梯口上楼消耗的时间更短, 但是挂在了第九个用例, 因为只考虑了当前楼层, 而没有结合以后楼层的情况进行考虑, 所以并不是最优, 说到这里, 这就有点DP的味道了!的确, 看了大佬们的代码, 看到了很多用DP解决。
瞎搞 : 其实贪心是可以很快写出来的, 又是没有使用模块化思想, 代码又长又臭, Debug了挺久。还有就是又没有考虑清楚当前的贪心策略会不会有BUG和没有考虑清楚顶楼情况, 导致代码写出来比赛已经OVER了 /(ㄒoㄒ)/~~, 最后还错了!!!
贪心错误做法:
#include<bits/stdc++.h>
#define LL long long
#define ULL unsigned long long
#define lowbit(i) (i&(-i))
using namespace std;
const int INF = 0x3f3f3f3f;
int main(void)
{
][];
int n, m;
bool flag;
;
scanf("%d%d", &n, &m);
; i<=n; i++){
flag = false;
; j<=m+; j++){
char ch;
scanf("%c", &ch);
';
else j--;
) flag = true;
}
if(flag && !cnt) cnt = i;
}
bool L = true;
bool even;
)%==) even = true;
else even = false;
int ans;
) {puts(;}
else ans = n-cnt;
//printf("%d %d", cnt, ans);puts("");
; i--){
if(i==cnt){
if(L){
;
; j>=; j--){
){
temp = j;
break;
}
}
);
else{
ans+=temp-;
}
}else{
;
; j<=m+; j++){
){
temp = j;
break;
}
}
);
else{
ans+=(m+)-temp;
}
}
break;
}
if(L){
;
; j>=; j--){
){
temp = j;
break;
}
}
);
else{
if(even){
)/){
ans+=m+;
L = false;
}else{
ans+=temp-;
ans+=temp-;
}
}else{
)/) + ){
ans+=m+;
L = false;
}else{
ans+=temp-;
ans+=temp-;
}
}
}
}else{
;
; j<=m+; j++){
){
temp = j;
break;
}
}
);
else{
if(even){
)/){
ans+=m+;
L = true;
}else{
ans+=(m+)-temp;
ans+=(m+)-temp;
}
}else{
)/) + ){
ans+=m+;
L = true;
}else{
ans+=(m+)-temp;
ans+=(m+)-temp;
}
}
}
}
}
printf("%d\n", ans);
;
}
以下代码枚举做法, 由于有黏贴贪心时所写的代码, 所以又长又臭, 凑合着看吧
#include<bits/stdc++.h>
#define LL long long
#define ULL unsigned long long
#define lowbit(i) (i&(-i))
using namespace std;
const int INF = 0x3f3f3f3f;
LL ans = INF;
int F;
][];
int n, m;
bool flag;
;
void dfs(bool pre, bool now, int x, LL sum)//参数分别代表上一层所在的楼梯口位置, 和当前将要去往的楼梯口位置, 当前楼层数, 以及耗费了多少时间
{
if(pre){//如果上一层是在左楼梯
if(x==F){//如果在顶楼, 需要特殊处理
;
; j>=; j--){
){
tmp = j;
break;
}
}
)sum+=tmp-;
}else{
if(now){
;
; j>=; j--){
){
tmp = j;
break;
}
}
){
sum += *(tmp-);
}
}else{
sum += m+;
}
}
}else{
if(x==F){
;
; j<=m+; j++){
){
tmp = j;
break;
}
}
) sum+=(m+)-tmp;
}else{
if(now){
sum += m+;
}else{
;
; j<=m+; j++){
){
tmp = j;
break;
}
}
){
sum += *(m+ - tmp);
}
}
}
}
if(x!=F){
dfs(now, , sum);
dfs(now, , sum);
}else{
if(sum<ans) ans = sum;
return;
}
}
int main(void)
{
scanf("%d%d", &n, &m);
; i--){
flag = false;
; j<=m+; j++){
char ch;
scanf("%c", &ch);
';
else j--;
) flag = true;
}
if(flag && !cnt) cnt = i;
}
bool L = true;
) {puts(;}//所有楼层都是灯灭的
else F = cnt;//记录有效顶楼
dfs(, );//从第一层去往左楼梯上楼
dfs(, );//从第一层去往右楼梯上楼
printf();//每一层消耗的体力还要加上上楼梯花费的体力
;
}
#417 Div2 Problem B Sagheer, the Hausmeister (DFS && 枚举)的更多相关文章
- #417 Div2 Problem C Sagheer and Nubian Market (二分 && std::accumulate)
题目链接 : http://codeforces.com/problemset/problem/812/C 题意 : 给你 n 件物品和你拥有的钱 S, 接下来给出这 n 件物品的价格, 这些物品的价 ...
- Codeforces Round #417 (Div. 2) B. Sagheer, the Hausmeister —— DP
题目链接:http://codeforces.com/problemset/problem/812/B B. Sagheer, the Hausmeister time limit per test ...
- CodeForce-812B Sagheer, the Hausmeister(DFS)
Sagheer, the Hausmeister CodeForces - 812B 题意:有一栋楼房,里面有很多盏灯没关,为了节约用电小L决定把这些灯都关了. 这楼有 n 层,最左边和最右边有楼梯. ...
- Codeforces Round #417 (Div. 2) B. Sagheer, the Hausmeister
http://codeforces.com/contest/812/problem/B 题意: 有n层楼,每层楼有m个房间,1表示灯开着,0表示灯关了.最两侧的是楼梯. 现在每从一个房间移动到另一个房 ...
- 【动态规划】Codeforces Round #417 (Div. 2) B. Sagheer, the Hausmeister
预处理每一层最左侧的1的位置,以及最右侧的1的位置. f(i,0)表示第i层,从左侧上来的最小值.f(i,1)表示从右侧上来. 转移方程请看代码. #include<cstdio> #in ...
- Codeforces Round #417 B. Sagheer, the Hausmeister
B. Sagheer, the Hausmeister time limit per test 1 second memory limit per test 256 megabytes Som ...
- #417 Div2 B
#417 Div2 B 题意 给定一个01矩阵表示一幢楼,左右两侧是楼梯,中间是房间,1代表那个房间开灯,0代表关灯,现在某人从1层左端楼梯开始关掉所有灯,当移动某一层时,必须关掉当前层所有灯才能移动 ...
- AC日记——Sagheer, the Hausmeister codeforces 812b
812B - Sagheer, the Hausmeister 思路: 搜索: 代码: #include <cstdio> #include <cstring> #includ ...
- #417 Div2 E (树上阶梯博弈)
#417 Div2 E 题意 给出一颗苹果树,设定所有叶子节点的深度全是奇数或偶数,并且包括根在内的所有节点上都有若干个苹果. 两人进行游戏,每回合每个人可以做下列两种操作中的一种: 每个人可以吃掉某 ...
随机推荐
- 【VS开发】如何移植对话框?
[VS开发]如何移植对话框? 标签:[VS开发] 问题描述:当开发好一个可视化界面的时候,想将其移植到另外的工程中,这个时候希望能够导出对话框资源,好直接在另一个工程中进行编辑,而不用再次编辑对话框上 ...
- oracle ojdbc 版本须对应,否则日期字段查询结果与实际值可能不一致
1. 数据库版本:select * from v$version; 2. 版本对应:
- dp常见优化方法
noip范围内的dp优化方法: 加速状态转移 1.前缀和优化 2.单调队列优化 3.线段树或树状数组优化 精简状态 3:精简状态往往是通过对题目本身性质的分析,去省掉一些冗余的状态.相对以上三条套路性 ...
- Git_初步了解
Git入门篇 一:Git是什么?Git是目前世界上最先进的分布式版本控制系统.工作原理 / 流程: Workspace:工作区Index / Stage:暂存区Repository:仓库区(或本地仓库 ...
- linux查看网络ip得两个命令ifconfig和 ip addr
在安装linux 得时候,我们要选择桥接网络,相当于本电脑和虚拟机得电话都是接通外网,linux查看网络ip得两个命令ifconfig和 ip addr 1,命令ifconfig 如果ifconfig ...
- 双连通分量(点-双连通分量&边-双连通分量)
概念: 双连通分量有点双连通分量和边双连通分量两种.若一个无向图中的去掉任意一个节点(一条边)都不会改变此图的连通性,即不存在割点(桥),则称作点(边)双连通图. 一个无向图中的每一个极大点(边)双连 ...
- filebeat->redis->logstash->elasticsearch->kibana
整体流程 filebeat收集openresty应用日志传输到Redis集群中 Logstash从Redis集群中拉取数据,并传输到Elasticsearch集群 使用Kibana可视化索引 使用El ...
- IntelliJ IDEA 远程调试 Tomcat 的方法
在调试代码的过程中,为了更好的定位及解决问题,有时候需要我们使用远程调试的方法.在本文中,就让我们一起来看看,如何利用 IntelliJ IDEA 进行远程 Tomcat 的调试. 首先,配置remo ...
- Thymeleaf后台传值读取
/** * 测试用Controller * * @author * @date 2019-08-15 */@Controller@RequestMapping("/danyu/test& ...
- 使用 dataset 管理数据(官网)
ECharts 4 开始支持了 dataset 组件用于单独的数据集声明,从而数据可以单独管理,被多个组件复用,并且可以基于数据指定数据到视觉的映射.这在不少场景下能带来使用上的方便. ECharts ...