题目链接: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();//每一层消耗的体力还要加上上楼梯花费的体力
    ;
}

最新文章

  1. CocoaPods安装及使用详情
  2. 微信支付之JSAPI开发第一篇-基本概念
  3. 安装文件制作工具Wix概念快速入门
  4. Linux基本操作命令总结
  5. linux下安装filezilla客户端遇到的问题
  6. lua分割字符串终究版(转载,有改动)
  7. android ListView下拉刷新 上拉加载更多
  8. 结构体buf_page_t
  9. Dijkstra算法求解最短路径分析
  10. c# 循环语句练习题;
  11. CentOS最小化安装后启用无线连接网络
  12. powerdesinger(MSSQLSRV2008测试通过)通过Name或comment 导出注释到sql脚本,生成sql的说明备注,包括表注释信息
  13. 网络通信 --&gt; IO多路复用之select、poll、epoll详解
  14. Javascript的console[&#39;&#39;]几种常用输入方法
  15. Spring 进入Controller前参数校验
  16. 【Java】关于项目启动大请求量高负载时如何确保db等资源不出错的问题
  17. JDK8 新特性流式数据处理
  18. laravel orm
  19. linux du
  20. 使用组件构建Android应用程序

热门文章

  1. jmeter对websocket进行压测
  2. Dubbo基础、高级讲解
  3. GTS原理、架构
  4. 小记---------linux远程连接集群内其他机器mysql库
  5. python中判断变量的类型
  6. ubuntu18下lamp虚拟路劲配置
  7. numpy-数据格式之 int 与 uint
  8. Java Script 基本知识点
  9. Mac下的常用快捷键总结
  10. h5与app混合开发,jsbridge