AStar 最坏情况\(O(log_2560 ^ 4)\)

用\(AStar\)算法做了这题,程序跑了\(408ms\)。

相比于\(IDA*\)的\(100ms\)左右要慢上不少。

且\(A*\)由于是\(bfs\),代码长度也较长。

跑的慢的原因应该有两点:

  • 用了三个\(STL\),垃圾STL毁我青春
  • 这题的指数暴涨,是\(560\),所以\(log\)反而比前几次叠加要大。

使用的估价函数是一样的,即:

\(h(n) = \lceil\frac{相邻位置不对的对数}{3}\rceil\)

估价函数详细的证明 & 解释见 y总的题解


总结了一下应该在何时选择 \(A*\) 或 \(IDA*\):

  • 需要最小字典序时,状态表示很大,指数增长较快时,使用\(IDA*\)
  • 若状态容易表示,指数增长较慢时,使用\(A*\)(注意需要最小字典序时不能用\(A*\),因为他不是按照顺序搜索的)。

C++ 代码

  1. #include <cstdio>
  2. #include <iostream>
  3. #include <unordered_set>
  4. #include <queue>
  5. using namespace std;
  6. typedef unsigned long long ULL;
  7. const int N = 15, B = 17;
  8. int n;
  9. struct State{
  10. //v表示当前的状态,step表示步数,f表示当前估计值(答案)
  11. int v[N], step, f;
  12. //重载小于号
  13. bool operator < (const State &x) const{
  14. return f > x.f;
  15. }
  16. }Start;
  17. //检测是否到了目标状态
  18. bool check(State x){
  19. for(int i = 0; i < n; i++)
  20. if(x.v[i] != i + 1) return false;
  21. return true;
  22. }
  23. //用于检测一个状态是否已经访问过了
  24. unordered_set<ULL> s;
  25. priority_queue<State> q;
  26. //hash
  27. ULL get(State x){
  28. ULL res = 0;
  29. for(int i = 0; i < n; i++)
  30. res = res * B + x.v[i];
  31. return res;
  32. }
  33. int f(State x){
  34. int res = 0;
  35. for(int i = 1; i < n; i++)
  36. if(x.v[i] - 1 != x.v[i - 1]) res++;
  37. return res % 3 ? res / 3 + 1 : res / 3;
  38. }
  39. int bfs(){
  40. while(q.size()) q.pop();
  41. Start.step = 0; Start.f = f(Start);
  42. q.push(Start); s.insert(get(Start));
  43. while(!q.empty()){
  44. State u = q.top(); q.pop();
  45. if(u.f >= 5) return 5;
  46. if(check(u)) return u.step;
  47. for(int l = 1; l < n; l++){
  48. for(int i = 0; i + l - 1 < n; i++){
  49. int j = i + l - 1;
  50. for(int k = i + l; k < n; k++){
  51. State v;
  52. for(int f = 0; f < n; f++) v.v[f] = u.v[f];
  53. for(int f = j + 1, t = i; f <= k; f++, t++)
  54. v.v[t] = u.v[f];
  55. for(int f = i, t = i + k - j; f <= j; f++, t++)
  56. v.v[t] = u.v[f];
  57. if(s.count(get(v)) > 0) continue;
  58. s.insert(get(v));
  59. v.step = u.step + 1;
  60. v.f = v.step + f(v);
  61. q.push(v);
  62. }
  63. }
  64. }
  65. }
  66. return 5;
  67. }
  68. int main(){
  69. int T; scanf("%d", &T);
  70. while(T--){
  71. s.clear();
  72. scanf("%d", &n);
  73. for(int i = 0; i < n; i++)
  74. scanf("%d", &Start.v[i]);
  75. int res = bfs();
  76. if(res >= 5) puts("5 or more");
  77. else printf("%d\n", res);
  78. }
  79. return 0;
  80. }

AcWing 180. 排书的更多相关文章

  1. AcWing 1023. 买书 完全背包

    //完全背包 求方案数目 //f[i][j] 只从前i个物品中选,且总体积恰好为j的方案的集合 //f[i][j]=f[i-1][j]+f[i-1][j-v*1]+f[i-1][j-v*2]+...f ...

  2. AcWing 【算法提高课】笔记02——搜索

    搜索进阶 22.4.14 (PS:还有 字串变换 A*两题 生日蛋糕 回转游戏 没做) 感觉暂时用不上 BFS 1. Flood Fill 在线性时间复杂度内,找到某个点所在的连通块 思路 统计连通块 ...

  3. python库-collections模块Counter类

    Counter类主要是用来跟踪值出现的次数.它是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为value. demo: all_words = [] # 列表里面是汉字(可 ...

  4. [No00005F]读书与心智

    读千卷书,行万里路,不够…还得有个对谈者相伴,才更有意思.十月七号晚上,与友人谈读书,线上直播,三百观众相伴,四小时畅谈,不亦乐乎! Part1:读书的载体 散发出最浓郁的知识芬芳和铭刻下最隽永的历史 ...

  5. 本周实验的PSP0过程文档

    项目计划总结:       日期/任务      听课        编写程序         阅读相关书籍 日总计          周一      110           60         ...

  6. CodeForces 294B Shaass and Bookshelf 【规律 & 模拟】或【Dp】

    这道题目的意思就是排两排书,下面这排只能竖着放,上面这排可以平着放,使得宽度最小 根据题意可以得出一个结论,放上这排书的Width 肯定会遵照从小到大的顺序放上去的 Because the total ...

  7. 第三周pspo过程文档

    团队协作:     日期/任务      听课        编写程序         阅读相关书籍 日总计          周一      110          60             ...

  8. pspo过程文档

    项目计划总结:       日期/任务      听课        编写程序         阅读相关书籍 日总计          周一      110          60         ...

  9. 《Word排版艺术》读后感,兼谈LaTeX

    我有两年多的LaTeX使用经验,用它排实验报告.毕业论文和书籍(半本):Word的使用时间长一些,但真正用好也不过是近一两年的事.这两个软件我都 用得很熟,我想我可以一边谈谈读<Word排版艺术 ...

随机推荐

  1. 3-colorability

    目录 1.1 3-colorability 1.1.1 3元可满足规约到3着色 1.1.2 证明充分和必要性 1.1 3-colorability 一个图的三着色问题:要使得边两头的结点颜色互不相同. ...

  2. 算法题目:北邮python 3-C 排队前进

    一道python作业的题目,比较有意思,题目如下: 题目描述 有 n 个人排队向一个方向前进,他们前进的速度并不一定相同. 最开始即 t=0 时,每个人的位置并不相同.可以把他们放在数轴上,设他们前进 ...

  3. ubuntu 18.04安装RTL8821CE无线网卡驱动

    疫情期间闲下来无聊,把办公室的旧机器装了ubuntu,但是无法连接无线网. 打开终端 #查看无线网卡信息. -i 是不区分大小写 tjj@ubuntu:~/Documents$ lspci | gre ...

  4. deepin 安装最新版node

    安装npm sudo apt install npm 安装node sudo npm install -g n 升级node到稳定版 sudo n stable 升级到最新版 sudo n lates ...

  5. curl 超时问题解决

    curl -o /dev/null -s -w %{time_namelookup}---%{time_connect}---%{time_starttransfer}---%{time_total} ...

  6. git 强制更新本地和强制提交覆盖

    强制更新覆盖本地: git pull时出现冲突 放弃本地修改,使远程库内容强制覆盖本地代码git fetch --all //只是下载代码到本地,不进行合并操作git reset --hard ori ...

  7. xss攻击与防范

    xss攻击方式以及防范 通常来说,网站一般都是有着,用户注册,用户登录,实名认证等等这些需要用户把信息录入数据库的接口 xss找的就是这种接口,他们可以在传递数据的时候,传递恶意的  script  ...

  8. Go语言实现excel导入无限级菜单结构

    目录 需求 实现 测试 简单例子 复杂例子 需求 最近有一个需求,要实现一个无限级结构的树型菜单,差不多长下面这个样子 我们知道无限级实现思路都是用一个parent_id将各种层级串联起来,顶级的pa ...

  9. Vegas教程:教你制作抖音热门人物穿越门窗特效

    抖音上经常会有很多特效视频,例如换妆.分镜.合拍.放大等,合适的特效总是会让视频更加出彩.这些特效,除了一部分是抖音自带以外,很多都是用的其他视频特效软件制作而成.这些视频编辑软件操作简单易上手,强大 ...

  10. js 时间日期与时间戳之间转换

    1 1.将时间(2017-08-10)转换时间戳 2 var startTime = '2017-08-10'; 3 var startdate = new Date(Date.parse(start ...