QwQ太懒了,题目直接复制uoj的了

QwQ这个题可以说是十分玄学的一道题了

首先可以暴搜,就是\(dfs\)然后模拟每个过程是哪个柱子向哪个柱子移动

不多解释了,不过实现起来还是有一点点难度的

直接上代码吧

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. #include<cstring>
  5. #include<cmath>
  6. #include<queue>
  7. using namespace std;
  8. inline int read()
  9. {
  10. int x=0,f=1;char ch=getchar();
  11. while (!isdigit(ch)) {if (ch=='-') f=-1;ch=getchar();}
  12. while (isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
  13. return x*f;
  14. }
  15. const int maxn = 110;
  16. const int mod = 998244353;
  17. int a[maxn][maxn];
  18. int bel[maxn];
  19. int top[maxn];
  20. int st[maxn];
  21. int ed[maxn];
  22. int num;
  23. int n,m;
  24. int ans;
  25. void to(int i,int j)
  26. {
  27. int x = a[i][top[i]];
  28. if (ed[x]==i) num--;
  29. a[i][top[i]--]=0;
  30. a[j][++top[j]]=x;
  31. if (ed[x]==j) num++;
  32. }
  33. void dfs(int tmp)
  34. {
  35. //for (int i=1;i<=3;i++)
  36. //{
  37. // cout<<"第"<<i<<"个柱子: " ;
  38. // for (int j=1;j<=top[i];j++)
  39. // {
  40. // cout<<a[i][j]<<" ";
  41. // }
  42. // cout<<endl;
  43. //}
  44. //cout<<"---------------------"<<endl;
  45. if (num==n){ans++;if (ans>mod) ans-=mod;};
  46. if (tmp==m+1) return;
  47. for (int i=1;i<=3;i++)
  48. {
  49. for (int j=1;j<=3;j++)
  50. {
  51. if (i==j) continue;
  52. if (top[i]<=0) continue;
  53. if (a[i][top[i]]>a[j][top[j]] && top[j]>0) continue;
  54. to(i,j);
  55. dfs(tmp+1);
  56. to(j,i);
  57. }
  58. }
  59. }
  60. int main()
  61. {
  62. scanf("%d%d",&n,&m);
  63. if (m>14) {
  64. cout<<292996445%mod<<endl;
  65. return 0;
  66. }
  67. for (int i=1;i<=n;i++) st[i]=read();
  68. for (int i=1;i<=n;i++) ed[i]=read();
  69. for (int i=1;i<=n;i++) if (st[i]==ed[i]) num++;
  70. for (int i=n;i>=1;i--) a[st[i]][++top[st[i]]]=i;
  71. //cout<<num<<endl;
  72. dfs(1);
  73. cout<<ans;
  74. return 0;
  75. }

经过仔(guan)细(kan)思(ti)考(jie)不难发现,这个题,有用的状态只有\(3^n\)种,我们可以令\(f[i][j]\)表示当前的操作步数是\(i\),各个盘子的状态是\(j\)的合法移动方案数

然后记忆化一下!竟然过了!!!

具体的复杂度分析在这

不过这个题还是有很多记得学习的地方!

1.模拟移动的过程只需要考虑柱子,而不是盘子

2.记录状态的时候可以用vector+map来实现 很方便

上代码

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. #include<cstring>
  5. #include<cmath>
  6. #include<queue>
  7. #include<map>
  8. using namespace std;
  9. inline int read()
  10. {
  11. int x=0,f=1;char ch=getchar();
  12. while (!isdigit(ch)) {if (ch=='-') f=-1;ch=getchar();}
  13. while (isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
  14. return x*f;
  15. }
  16. const int mod = 998244353;
  17. const int maxn = 110;
  18. map<vector<int>,int> f[maxn],g[maxn];
  19. int a[maxn],b[maxn];
  20. int n,m;
  21. vector<int> v,vv;
  22. int ans=0;
  23. int dfs(vector<int> x,int num)
  24. {
  25. int cnt=0,top[10];
  26. if (num<0) return 0;
  27. memset(top,127/3,sizeof(top));
  28. if (g[num][x]) return f[num][x];
  29. g[num][x]=1;
  30. x.resize(n);
  31. // for (int i=n-1;i>=0;i--) cout<<x[i]<<endl<<endl;
  32. for (int i=n-1;i>=0;i--) top[x[i]]=i;
  33. for (int i=1;i<=3;i++)
  34. for (int j=1;j<=3;j++)
  35. {
  36. if (i==j) continue;
  37. if (top[i]<top[j])
  38. {
  39. x[top[i]]=j;
  40. cnt=(cnt+dfs(x,num-1))%mod;
  41. x[top[i]]=i;
  42. }
  43. }
  44. f[num][x]=cnt;
  45. return f[num][x];
  46. }
  47. int main()
  48. {
  49. scanf("%d%d",&n,&m);
  50. for (int i=1;i<=n;i++) a[i]=read(),v.push_back(a[i]);
  51. for (int i=1;i<=n;i++) b[i]=read();
  52. f[0][v]=1;
  53. g[0][v]=1;
  54. v.clear();
  55. for (int i=1;i<=n;i++) vv.push_back(b[i]);
  56. for (int i=0;i<=m;i++)
  57. {
  58. ans=(ans+dfs(vv,i))%mod;
  59. }
  60. cout<<ans;
  61. return 0;
  62. }

uoj167 元旦老人与汉诺塔(记忆化搜索)的更多相关文章

  1. [UOJ #167]【UR #11】元旦老人与汉诺塔

    题目大意:给你一个有$n$个盘子的汉诺塔状态$S$,问有多少种不同的操作方法,使得可以在$m$步以内到达状态$T$.$n,m\leqslant100$ 题解:首先可以知道的是,一个状态最多可以转移到其 ...

  2. UR11 A.元旦老人与汉诺塔

    题目:http://uoj.ac/contest/23/problem/167 如果我们拿个map来存状态的话.设当前状态是v,下一个状态是s.有f[i+1][s]+=f[i][v]. 初始f[0][ ...

  3. 奇妙的算法【4】-汉诺塔&哈夫曼编码

    1,汉诺塔问题[还是看了源码才记起来的,记忆逐渐清晰] 汉诺塔:汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具.大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着6 ...

  4. 算法笔记_013:汉诺塔问题(Java递归法和非递归法)

    目录 1 问题描述 2 解决方案  2.1 递归法 2.2 非递归法 1 问题描述 Simulate the movement of the Towers of Hanoi Puzzle; Bonus ...

  5. C#递归解决汉诺塔问题(Hanoi)

    using System;using System.Collections.Generic;using System.Linq;using System.Text; namespace MyExamp ...

  6. 数据结构0103汉诺塔&八皇后

    主要是从汉诺塔及八皇后问题体会递归算法. 汉诺塔: #include <stdio.h> void move(int n, char x,char y, char z){ if(1==n) ...

  7. Conquer and Divide经典例子之汉诺塔问题

    递归是许多经典算法的backbone, 是一种常用的高效的编程策略.简单的几行代码就能把一团遭的问题迎刃而解.这篇博客主要通过解决汉诺塔问题来理解递归的精髓. 汉诺塔问题简介: 在印度,有这么一个古老 ...

  8. 几年前做家教写的C教程(之四专讲了指针与汉诺塔问题)

    C语言学习宝典(4) 指针:可以有效的表示复杂的数据结构,能动态的分配动态空间,方便的使用字符串,有效的使用数组,能直接处理内存单元 不掌握指针就没有掌握C语言的精华 地址:系统为每一个变量分配一个内 ...

  9. python实现汉诺塔

    经典递归算法汉诺塔分析: 当A柱子只有1个盘子,直接A --> C 当A柱子上有3个盘子,A上第一个盘子 --> B, A上最后一个盘子 --> C, B上所有盘子(1个) --&g ...

随机推荐

  1. linux安装mysql80

    打开网址:https://dev.mysql.com/downloads/repo/yum/,选择对应li 安装mysql源 yum -y localinstall mysql80-community ...

  2. 神舟G7-CT7NK 安装tensorflow-gpu

    参考https://www.cnblogs.com/xbit/p/9768238.html 直接安装,运行keras mnist数字识别报错: Could not create cudnn handl ...

  3. Mysql索引最佳实践笔记0524

    #mysql5.7 innodb默认存储引擎 一.关于索引二.最佳实践三.避坑实践 一.关于索引 1.索引的作用 -提高查询效率 -数据分组.排序 -避免回表查询 -优化聚集查询 -用于多表join关 ...

  4. Hopper Disassembler系列之Sublime Text 3 爆破

    https://www.52pojie.cn/thread-793069-1-1.html 当参数少于7个时, 参数从左到右放入寄存器: rdi, rsi, rdx, rcx, r8, r9. 当参数 ...

  5. 设置 ajax 同步获取数据

    问题 在处理DataTable的render进行列表渲染的时候发现通过ajax发送请求,返回的值并不正确. {"data":"id","render& ...

  6. 【CSS】拼图验证练习

    抄自B站Up主CodingStartup起码课 <!DOCTYPE html> <html lang="en"> <head> <meta ...

  7. 利用Struts2拦截器完成文件上传功能

    Struts2的图片上传以及页面展示图片 在上次的CRUD基础上加上图片上传功能 (https://www.cnblogs.com/liuwenwu9527/p/11108611.html) 文件上传 ...

  8. WEB漏洞——SQL

    由于我的博客是学到渗透的时候才做的,没有关于WEB漏洞的笔记,现在发现WEB层面的漏洞有些不太熟悉了,边写一下笔记边复习一下,就从sql注入开始吧 话不多说先上大佬写的表[ctfhub]SQL注入 - ...

  9. 五分钟搞懂MySQL索引下推

    大家好,我是老三,今天分享一个小知识点--索引下推. 如果你在面试中,听到MySQL5.6"."索引优化" 之类的词语,你就要立马get到,这个问的是"索引下推 ...

  10. 20210716考试-NOIP16

    考场时Prim的 $i$ 写成 $k$ 100->0 rank1->rank23 T1 Star Way To Heaven 考场正解:假设你要二分答案,则几个圆组成几道"屏障& ...