原题链接: https://www.acwing.com/problem/content/188/

题目描述

一名男子在12:00抵达了某巴士站,并且在12:00-12:59期间他将在那里逗留。
巴士站有很多巴士路线,巴士抵达的时间均已给出。
该男子观察巴士的抵达时间,有所发现:
1、在12:00 ~12:59 期间,同一线路上的巴士以相同的时间间隔到站。
2、每条巴士线路至少有两辆车到达本站。
3、不同线路的巴士可以同时到达本站。
4、不同巴士线路的车首次到达本站的时间和到站的时间间隔都有可能相同。
5、测试用例中的总线路不会超过17条。
请你编写一个程序,求出在所有巴士到达本站的时刻满足输入数据的要求的情况下,巴士线路的总数量最小是多少。
输入格式
输入数据第一行包含整数n,表示在这一小时内抵达到该站的巴士总数量。
第二行包含n个整数,表示按升序排序得到的n个巴士的到站时间。
输出格式
输出一个整数,表示最小巴士线路数。
数据范围
1≤n≤300
输入样例:
17
0 3 5 13 13 15 21 26 27 29 37 39 39 45 51 52 53
输出样例:
3

题解

首先预处理出所有可能的线路。先枚举起点i,再枚举公差j,则i和j需要满足两个条件:
由于i是起点,因此0 ~ i - 1中不能包含任何该序列的点,所以公差j至少是i + 1;
由于0 ~ 59之间至少要包含两个点,因此i + j一定小于60;
剩下的问题变成:
最少从合法线路中选出多少条,才可以覆盖所有给定的公交车。
由于总路线数量较多,最多从中选出17条,但实现我们并不知道该选多少条,因此可以采用迭代加深搜索。
剪枝:
1.由于是枚举组合数,并不是排列数,为了避免重复在DFS时传入当前枚举的起点。
2.将所有等差数列按长度排序,优先枚举长度较长的等差数列。这样在搜索树中前几层的分支少,可以更快地发现矛盾然后回溯。
3.由于剪枝2的存在,当前路线覆盖的点数是最多的,如果当前路线能覆盖的点数 * 剩余可选的路径条数 + 当前已经覆盖的点数 < 总点数,说明当前方案一定非法,直接回溯即可。

#include <iostream>
#include <cstring>
#include <algorithm>using namespace std;
typedef pair<int, int> PII;const int M = 60;int bus[M];
int n;
vector<pair<int, PII>> routes;bool is_route(int a, int b)
{for(int i = a; i < 60; i += b){if(!bus[i]) return false;}return true;
}bool dfs(int depth, int u, int sum, int start) //剪枝一
{if(u == depth) return sum == n;if(routes[start].first * (depth - u) + sum < n) return false; //剪枝3for(int i = start; i < routes.size(); i++) //注意:搜索的是路径{auto r = routes[i];int dist = r.first;int a = r.second.first, d = r.second.second;if(!is_route(a, d)) continue;for(int k = a; k < 60; k += d) bus[k]--;if(dfs(depth, u + 1, sum + dist, i)) return true;for(int k = a; k < 60; k += d) bus[k]++;}return false;
}int main()
{cin >> n;for(int i = 0; i < n; i++){int t;scanf("%d", &t);bus[t]++;}for(int i = 0; i < 60; i++) //枚举起点{for(int j = i + 1; i + j < 60; j++) //枚举公差{if(is_route(i, j)){routes.push_back({(59 - i)/ j + 1, {i, j}}); //覆盖点数 + 路线}}}sort(routes.begin(), routes.end(), greater<pair<int, PII>>()); //剪枝2int depth = 0;while(!dfs(depth, 0, 0, 0)) depth++;cout << depth << endl;return 0;
}

题解参考:

yxc 大神: https://www.acwing.com/solution/content/4221/

巴士(DFS迭代加深 + 剪枝)相关推荐

  1. Gym - 102460A Rush Hour Puzzle(dfs迭代加深)

    题目链接:点击查看 题目大意:给出一个 6 * 6 的矩阵,表示华容道的游戏界面,现在需要红色汽车(标号为 1 )从第三行最右端到达出口的最短时间,如果无解或者步数超过 10 输出 -1 题目分析:因 ...

  2. POJ - 2248 Addition Chains(dfs+迭代加深)

    题目链接:点击查看 题目大意:我们规定加法链有如下特点: 现在给出一个数n,求该数的最短加法链 题目分析:这个题首先我们可以枚举所有可能性,并且进行适当的剪枝: 当前长度大于等于最优解时回溯 当前值等 ...

  3. 洛谷 P2534 [AHOI2012]铁盘整理(IDA*(dfs+迭代加深+估值函数))

    题目链接:P2534 [AHOI2012]铁盘整理 题解:本篇为IDA*的应用,做这题前建议先做前一篇文章的题目:点这 这题中难在估值函数的确定,总的来说IDA*基本上格式都差不多,主要难在估值函数的 ...

  4. 再探深搜之剪枝、迭代加深及双向搜索

    一.剪枝 剪枝的基本方法: 1.优化搜索顺序 2.排除等效冗余 3.可行性剪枝(上下界剪枝) 4.最优性剪枝 例题1:AcWing 167.木棒 这题首先很容易想出暴力的代码:从小到大枚举木棍总长度的 ...

  5. P2324 [SCOI2005]骑士精神(迭代加深搜索,dfs)

    传送门 文章目录 解析 解析 很显然,让马走的话状态记录和转移都会比较复杂 所以转化成让空位跳会更好做一点 但这不是重点 初看本题,其实第一感觉是bfs 但是状态数理论上最差可以达到815,(当然基本 ...

  6. DFS,BFS和迭代加深的联系与区别

    关于DFS: DFS算法是沿着搜索树的根节点,一直遍历完该搜索树之后再回溯继续搜索的一种算法.缺点是可能会出现答案在搜索树层数很浅,在靠后的子树中,但由于搜索次序需要遍历完一棵搜索树所有的节点,所以导 ...

  7. 迭代加深搜索与埃及分数求解

    迭代加深搜索,实质上是限定下界的深度优先搜索.即首先允许深度优先搜索K层,若没有发现可行解,再将K+1后 重复以上步骤搜索,直到搜索到可行解. 在迭代加深搜索的算法中,连续的深度优先搜索被引入,每一个 ...

  8. 埃及分数问题+迭代加深搜索

    理论上可以用回溯法求解,但是解答树非常恐怖,其一深度没有明显上限,1/i的值似乎可以在枚举不断更大的i时越来越小:其二加数的选择在理论上无限制. 解决方案采用迭代加深搜索:从小到大枚举深度上限maxd ...

  9. POJ2248 Addition Chains(迭代加深搜索)

    题目链接: poj2248 题目大意 给你一个数字n,你需要构造一个首项为1,末项为n的递增序列,并且这个序列的非首项的数字都能从它前面找到两项之和与之相等,前面的两项可以为同一项,即可重复,并且要让 ...

最新文章

  1. Windows驱动开发 - 派遣函数
  2. c++ list 获取元素_Python中最常见的10个问题(list)
  3. ubuntu grub 操作
  4. 利用Ajax实现DataGrid无刷新分页(AjaxGrid)【转】
  5. BAT中如何使用for循环
  6. 用java实现学生成绩管理系统(附有详细代码)
  7. linux命令行下载gcc,linux安装GCC详解
  8. 电脑文件无法删除怎么办?
  9. 虚拟摄像头驱动程序彻底分析
  10. 我来告诉你,一个草根程序员如何逆袭,成功进入BAT!
  11. 从零开始安装和配置vim (还是vscode香)
  12. ZZULIOJ1076-1080Python解法
  13. 什么是熔断? 熔断有哪几种状态 ?断路器的工作原理
  14. 使用`rfkill`控制WIFI开关与`wpa_supplicant`的影响
  15. grafana是什么?
  16. android仿抖音礼物列表实现,Android仿抖音列表效果
  17. pandas添加一行数据的方法
  18. 【恩墨有约成都站】Kamus和老熊与你相约,不止是技术
  19. 知识丨软件定义汽车的价值
  20. pytest基础知识一

热门文章

  1. SecureCRT自动保存日志设置
  2. 20-30岁怎么规划自己的人生呢?
  3. 看见“信任”,可信计算史上最全解析
  4. Excel上传,加密,解析
  5. 智慧城市背景下的“多规合一”标准探究
  6. 面试官:IoC 和 DI 有什么区别?
  7. 【MVC、Spring MVC介绍、区别、执行流程】
  8. Android在虚拟机和安卓机上运行不了
  9. 让别人远程访问你的代码网站项目或临时演示你的项目给客户的方式详解即外网局域网访问自己的项目
  10. 论文研读笔记(二)——VGG