[UOJ #167]【UR #11】元旦老人与汉诺塔
题目大意:给你一个有$n$个盘子的汉诺塔状态$S$,问有多少种不同的操作方法,使得可以在$m$步以内到达状态$T$。$n,m\leqslant100$
题解:首先可以知道的是,一个状态最多可以转移到其他的$3$个状态,然后发现若$m\leqslant100$的话,每个柱子最多移动$7$个盘子,所以最多状态只有$3^{21}$次,这个数可能有点大,但是通过更严密的分析的话,最后状态数只有$10^5$级别,可以通过记忆化搜索通过。
卡点:妈啊,我怎么又把柱子上的顺序弄反了
C++ Code:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
const int mod = 998244353;
inline void reduce(int &x) { x += x >> 31 & mod; } int n, m, ans;
std::vector<int> S, T, v[3];
std::map<std::vector<int>, int> f[105];
int dfs(int x, std::vector<int> S, std::vector<int> *v) {
if (f[x].count(S)) return f[x][S];
if (!x) return 0;
int &F = f[x][S];
for (int i = 0; i < 3; ++i) if (v[i].size())
for (int j = 0; j < 3; ++j)
if (!v[j].size() || v[i].back() < v[j].back()) {
S[v[i].back()] = j;
v[j].push_back(v[i].back()), v[i].pop_back();
reduce(F += dfs(x - 1, S, v) - mod);
S[v[j].back()] = i;
v[i].push_back(v[j].back()), v[j].pop_back();
}
return F;
}
int main() {
std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
std::cin >> n >> m;
for (int i = 0, x; i < n; ++i) std::cin >> x, S.push_back(--x);
for (int i = 0, x; i < n; ++i) std::cin >> x, T.push_back(--x);
for (int i = n - 1; ~i; --i) v[T[i]].push_back(i);
f[0][S] = 1;
for (int i = 0; i <= m; ++i) reduce(ans += dfs(i, T, v) - mod);
std::cout << ans << '\n';
return 0;
}
[UOJ #167]【UR #11】元旦老人与汉诺塔的更多相关文章
- UR11 A.元旦老人与汉诺塔
题目:http://uoj.ac/contest/23/problem/167 如果我们拿个map来存状态的话.设当前状态是v,下一个状态是s.有f[i+1][s]+=f[i][v]. 初始f[0][ ...
- uoj167 元旦老人与汉诺塔(记忆化搜索)
QwQ太懒了,题目直接复制uoj的了 QwQ这个题可以说是十分玄学的一道题了 首先可以暴搜,就是\(dfs\)然后模拟每个过程是哪个柱子向哪个柱子移动 不多解释了,不过实现起来还是有一点点难度的 直接 ...
- UVA 10254 - The Priest Mathematician (dp | 汉诺塔 | 找规律 | 大数)
本文出自 http://blog.csdn.net/shuangde800 题目点击打开链接 题意: 汉诺塔游戏请看 百度百科 正常的汉诺塔游戏是只有3个柱子,并且如果有n个圆盘,至少需要2^n- ...
- 汉诺塔VII(递推,模拟)
汉诺塔VII Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submis ...
- C语言数据结构----递归的应用(斐波拉契数列、汉诺塔、strlen的递归算法)
本节主要说了递归的设计和算法实现,以及递归的基本例程斐波拉契数列.strlen的递归解法.汉诺塔和全排列递归算法. 一.递归的设计和实现 1.递归从实质上是一种数学的解决问题的思维,是一种分而治之的思 ...
- python 游戏 —— 汉诺塔(Hanoita)
python 游戏 —— 汉诺塔(Hanoita) 一.汉诺塔问题 1. 问题来源 问题源于印度的一个古老传说,大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆 ...
- 汉诺塔问题(Hanoi Tower)递归算法解析(Python实现)
汉诺塔问题 1.问题来源:汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从上往下从小到大顺序摞着64片黄金圆盘.上帝命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根 ...
- HDU 2587 - 很O_O的汉诺塔
看题传送门 吐槽题目 叫什么很O_O的汉诺塔我还@.@呢. 本来是想过一段时间在来写题解的,不过有人找我要. 本来排名是第8的.然后搞了半天,弄到了第五.不过代码最短~ 截止目前就9个ID过,小小的成 ...
- JAVA——汉诺塔
大家还记得某年春晚小品那个把大象放冰箱需要几步吗? 今天,我准备写的是汉诺塔,有三个魔法石柱,分别:诚实.勇敢.正直.其中有一个石柱上从大到小,从地向上依次排放着四个魔法圆环,需要将那四个魔法圆环分别 ...
随机推荐
- 洛谷 P1281 书的复制 题解
P1281 书的复制 题目背景 大多数人的错误原因:尽可能让前面的人少抄写,如果前几个人可以不写则不写,对应的人输出0 0. 不过,已经修改数据,保证每个人都有活可干. 题目描述 现在要把m本有顺序的 ...
- 原创:协同过滤之spark FP-Growth树应用示例
上一篇博客中,详细介绍了UserCF和ItemCF,ItemCF,就是通过用户的历史兴趣,把两个物品关联起来,这两个物品,可以有很高的相似度,也可以没有联系,比如经典的沃尔玛的啤酒尿布案例.通过Ite ...
- MATLAB关闭科学计数法显示
- 多维矩阵转一维数组(c++)【转载】
在由二维矩阵转为一维数组时,我们有两种方式:以列为主和以行为主. 以列为主的二维矩阵转为一维数组时,转换公式为: index=column+row×行数 以行为主的二维矩阵转为一维数组时,转换公式为: ...
- 【深入学习linux】系统分区与格式化
分区:把大硬盘分为小的逻辑分区 格式化:写入文件系统 分区设备文件名:给每个分区定义设备文件名 挂载:给每个分区分配挂载点 分区->格式化->取名->分配挂载点(WINDOW下的盘弧 ...
- python去除BOM头\ufeff等特殊字符
1.\ufeff 字节顺序标记 去掉\ufeff,只需改一下编码就行,把UTF-8编码改成UTF-8-sigwith open(file_path, mode='r', encoding='UTF-8 ...
- android -------- 流式布局,支持单选、多选等
最近开发中有流式标签这个功能,网上学了下,来分享一下 Android 流式布局,支持单选.多选等,适合用于产品标签等. 效果图: 用法: dependencies { compile 'com.hym ...
- # advanced packaging
目录 advanced packaging ASM NEXX ASMPT完成收購NEXX 準備就緒迎接先進半導體封裝之高速增長 Intro Bumping 产品供应 晶圆溅镀– Apollo 300 ...
- gdb命名记录
gdb常用命令 显示类 info locals 显示当前局部变量 info args 显示当前函数的参数 info sharedlibrary 显示当前程序依赖的动态库 ptype val 打印变量类 ...
- PAT 甲级 1080 Graduate Admission (30 分) (简单,结构体排序模拟)
1080 Graduate Admission (30 分) It is said that in 2011, there are about 100 graduate schools ready ...