zoukankan      html  css  js  c++  java
  • POJ 1167 The Buses(DFS经典)

    题意:

    一个人在12:00 ~ 12 :59 这个时间段,观察了一个汽车站台的公共汽车的来往情况,并且记录了每一辆车的到站时间。这些记录的车满足下面的情况:

    在12:00 ~12:59 期间,同一线路上的公共汽车以相同的时间间隔到站。

    1. 每条公共汽车线路至少有两辆车到达本站

    2. 来自不同线路的公共汽车可以同时到达本站

    3. 不同公共汽车线路的车首次到达本站的时间和到站的时间间隔都有可能相同

    求最小的汽车路线数。

    思路:

    1. 首先统计出所有可能的公共汽车时刻方案,存放在数组中,为了方便后面的剪枝发挥效果,对其在 1 小时内的停站次数从大到小排序;

    2. 下面 DFS 的过程比较出彩,不同于传统的深搜,这次是对于等差数列的元素成组消去,然后再还原;

    3. 题目中给出了最大的路线数为 17,可以以此为依据最大剪枝。对于向后选择路线时,对于到站次数的从大到小进行一个最小的预估,如果超出,则剪枝;

    #include <iostream>
    #include <algorithm> 
    using namespace std;
    
    struct ST {
        int arrive, interval, times;
        bool operator < (const ST& other) const { return times > other.times; }
    } route[1800];
    
    int N, hash[60], routecnt, ans;
    
    bool checkroute(int s, int delta) {
        for (int i = s; i < 60; i += delta) {
            if (!hash[i]) 
                return false;
        }
        return true;
    }
    
    void dfs(int k, int sum) {
        if (sum >= ans)
            return;
        if (N == 0) {
            ans = min(ans, sum);
            return;
        }
        for (int i = k; i < routecnt; i++) { 
            if (route[i].times > N)
                continue;
            if (sum + N/route[i].times >= ans)
                return;
            if (!checkroute(route[i].arrive, route[i].interval))
                continue;
    
            for (int j = route[i].arrive; j < 60; j += route[i].interval)
                N -= 1, hash[j] -= 1;
    
            dfs(i, sum + 1);
    
            for (int j = route[i].arrive; j < 60; j += route[i].interval)
                N += 1, hash[j] += 1;
        }
    }
    
    int main() {
        scanf("%d", &N);
        memset(hash, 0, sizeof(hash));
        for (int i = 0; i < N; i++) {
            int x;
            scanf("%d", &x);
            hash[x] += 1;
        }
        routecnt = 0;
        for (int i = 0; i < 30; i++) {
            for (int j = i + 1; j + i < 60; j++) {
                if (checkroute(i, j)) {
                    route[routecnt].arrive = i;
                    route[routecnt].interval = j;
                    route[routecnt].times = (59-i)/j + 1;
                    routecnt += 1;
                }
            }
        }
        sort(route, route + routecnt);
        ans = 17;
        dfs(0, 0);
        printf("%d\n", ans);
        return 0;
    }
  • 相关阅读:
    编译原理入门以及战大作业心得(2)汇编简易入门 康某
    简易聊天对话框(源码)
    用js做数字字母混合的随机四位验证码
    HTML5基础
    javascript基础
    jquery.AutoComplete 仿百度文本框感应
    DropDownlist显示树状
    利用 System.Net.Mail 实现邮件发送功能
    sql 根据字段值,查找属于哪个表中的哪个字段
    sql 查看数据库中的各表的大小
  • 原文地址:https://www.cnblogs.com/kedebug/p/2989448.html
Copyright © 2011-2022 走看看