#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 题意 给出一颗苹果树,设定所有叶子节点的深度全是奇数或偶数,并且包括根在内的所有节点上都有若干个苹果. 两人进行游戏,每回合每个人可以做下列两种操作中的一种: 每个人可以吃掉某 ...
随机推荐
- Java学习开发第二阶段总结
第二阶段的学习总结: 在这次学习中虽说任务量是比上次提升了不少.但大部分的内容都于C语言相同或者类似.学习起来相对来说很轻松.但也在这次学习中学到新的知识 ①Jshell 在cmd中运行Jshell脚 ...
- 【6.18校内test】T3细胞分裂
尽管T1T2很简单,但还是阻止不了我T3wa一片 细胞分裂[题目链接] xcg同学有一个80pts的代码 他说他的代码和我的很像,可惜我比较笨,只有30pts 其实这道题考场上是想到要分解质因数了,然 ...
- POJ 2955 Brackets 区间DP 入门
dp[i][j]代表i->j区间内最多的合法括号数 if(s[i]=='('&&s[j]==')'||s[i]=='['&&s[j]==']') dp[i][j] ...
- CSP-S 游记(算是AFO记 8)
Day-1 没什么好写的,还是一道题还是能调半天的状态 Day 0 假装出去旅游,结果公交车开了三个小时,状态直接爆炸 晚上颓了一下,最后还是 10 点睡的...真的当成是旅游了吧,只有到了比赛的时候 ...
- [.net core]3. Project 文件简介
这是一个C#的空的.net core web app .net frame work的.csproj 要编辑的话,得先卸载项目, .net core的.csproje不必要, .csproj 的文件 ...
- luogu P4383 [九省联考2018]林克卡特树lct
传送门 题目操作有点奇怪,不过可以发现这就是把树先变成\(k+1\)个连通块,然后每个连通块选一条路径(本题中一个点也是一条路径),然后依次接起来.所以实际上要求的是选出\(k+1\)条点不相交的路径 ...
- Linux下网络设置
1.临时IP配置 # ifconfig eth0 192.168.110.118 netmask 255.255.255.0 gateway 192.168.110.2 up # ...
- KVM虚拟化简介及安装
kvm是基于图形化的linux操作的 安装图形化界面的知识点: 磁盘空间有两个词: 精简置备:我先在我系统里面去声明我要一个50G的空间,但是呢,我不会把50G都分给你,你用多少,我分给你多少,但是做 ...
- Linux磁盘分区与lvm逻辑卷
硬盘接口的种类分四类:(价格由低到高) IDE SATA硬盘:别名串口硬盘,具有较强的纠错能力. SCSI硬盘:即采用SCSI接口的硬盘,SCSI接口具有应用范围广,多任务,带宽大,CPU占用率低. ...
- Qualcomm_Mobile_OpenCL.pdf 翻译-6-工作组尺寸的性能优化
对于许多kernels来说,工作组大小的调整会是一种简单有效的方法.这章将会介绍基于工作组大小的基础知识,比如如何获取工作组大小,为什么工作组大小非常重要,同时也会讨论关于最优工作组大小的选择和调整的 ...