题目描述

汉诺塔由三根柱子(分别用A、B、C表示)和n个大小互不相同的空心盘子组成。一开始n个盘子都摞在柱子A上,大的在下面,小的在上面,形成了一个塔状的锥形体。 对汉诺塔的一次合法的操作是指:从一根柱子的最上层拿一个盘子放到另一根柱子的最上层,同时要保证被移动的盘子一定放在比它更大的盘子上面(如果移动到空柱子上就不需要满足这个要求)。我们可以用两个字母来描述一次操作:第一个字母代表起始柱子,第二个字母代表目标柱子。例如,AB就是把柱子A最上面的那个盘子移到柱子B。汉诺塔的游戏目标是将所有的盘子从柱子A移动到柱子B或柱子C上面。 有一种非常简洁而经典的策略可以帮助我们完成这个游戏。首先,在任何操作执行之前,我们以任意的次序为六种操作(AB、AC、BA、BC、CA和CB)赋予不同的优先级,然后,我们总是选择符合以下两个条件的操作来移动盘子,直到所有的盘子都从柱子A移动到另一根柱子: (1)这种操作是所有合法操作中优先级最高的; (2)这种操作所要移动的盘子不是上一次操作所移动的那个盘子。 可以证明,上述策略一定能完成汉诺塔游戏。现在你的任务就是假设给定了每种操作的优先级,计算按照上述策略操作汉诺塔移动所需要的步骤数。

输入输出格式

输入格式:

输入有两行。第一行为一个整数n(1≤n≤30),代表盘子的个数。第二行是一串大写的ABC字符,代表六种操作的优先级,靠前的操作具有较高的优先级。每种操作都由一个空格隔开。

输出格式:

只需输出一个数,这个数表示移动的次数。我们保证答案不会超过10的18次方。

输入输出样例

输入样例#1:

3
AB BC CA BA CB AC
输出样例#1:

7
输入样例#2:

2
AB BA CA BC CB AC
输出样例#2:

5

说明

对于20%的数据,n ≤ 10。 对于100%的数据,n ≤ 30。

Solution:

  本题由于题面中说道按照上述方法一定能有答案。

  那么我们由普通的$hanoi$三塔的递推式:$d[i]=2*d[i-1]+1$(现实意义是将$i-1$个移动到$B$柱,再将$A$柱的一个移动到$C$柱,最后把$B$柱的$i-1$个移动到$C$柱),具体证明直接数归,还是比较简单的。

  然后扩展到本题,我们可以直接$dfs$处理出$n=1,2,3$的情况所对应的$d[1],d[2],d[3]$。

  由数归不难得出:$d[i]=k*d[i-1]+b$(可以类比普通$hanoi$塔)。

  则$k=\frac{d[3]-d[2]}{d[2]-d[1]},\;b=d[3]-d[2]*k$。

  最后$O(n)$递推即可得到$d[n]$了。

代码:

#include<bits/stdc++.h>
#define For(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
#define il inline
#define ll long long
using namespace std;
const int N=;
int n;
ll d[N];
int stk[][],cnt[];
struct node{
int fr,to;
}a[N];
bool vis[];
char s[];
il void dfs(int p,int c,int lst){
if(cnt[]==c||cnt[]==c){d[c]=p;return;}
For(i,,){
int j=a[i].fr,k=a[i].to;
if(cnt[j]&&j!=lst){
if(stk[j][cnt[j]]<stk[k][cnt[k]]||!stk[k][cnt[k]]){
stk[k][++cnt[k]]=stk[j][cnt[j]];
cnt[j]--;
dfs(p+,c,k);
break;
}
}
}
}
int main(){
scanf("%d",&n);
For(i,,){
scanf("%s",s);
a[i].fr=s[]-'A',a[i].to=s[]-'A';
}
stk[][++cnt[]]=;
dfs(,,-);
cnt[]=cnt[]=cnt[]=;
For(i,,)stk[][++cnt[]]=-i;
dfs(,,-);
cnt[]=cnt[]=cnt[]=;
For(i,,)stk[][++cnt[]]=-i;
dfs(,,-);
if(n<=)cout<<d[n];
else {
ll k=(d[]-d[])/(d[]-d[]),q=d[]-k*d[];
For(i,,n)d[i]=1ll*k*(d[i-])+q;
cout<<d[n];
}
return ;
}

P4285 [SHOI2008]汉诺塔的更多相关文章

  1. bzoj1019 / P4285 [SHOI2008]汉诺塔

    P4285 [SHOI2008]汉诺塔 递推 题目给出了优先级,那么走法是唯一的. 我们用$0,1,2$代表$A,B,C$三个柱子 设$g[i][x]$为第$x$根柱子上的$i$个盘子,经过演变后最终 ...

  2. BZOJ1019 汉诺塔/洛谷P4285 [SHOI2008]汉诺塔

    汉诺塔(BZOJ) P4285 [SHOI2008]汉诺塔 居然是省选题,还是DP!(我的DP菜得要死,碰见就丢分) 冥思苦想了1h+ \(\to\) ?! 就是普通的hanoi NOI or HNO ...

  3. P4285 [SHOI2008]汉诺塔 题解 (乱搞)

    题目链接 P4285 [SHOI2008]汉诺塔 解题思路 提供一种打表新思路 先来证明一个其他题解都没有证明的结论:\(ans[i]\)是可由\(ans[i-1]\)线性递推的. (\(ans[i] ...

  4. 1019: [SHOI2008]汉诺塔

    1019: [SHOI2008]汉诺塔 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 1495  Solved: 916[Submit][Status] ...

  5. bzoj1019 [SHOI2008]汉诺塔

    1019: [SHOI2008]汉诺塔 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 1030  Solved: 638[Submit][Status] ...

  6. BZOJ 1019: [SHOI2008]汉诺塔( dp )

    dp(x, y)表示第x根柱子上y个盘子移开后到哪根柱子以及花费步数..然后根据汉诺塔原理去转移... ------------------------------------------------ ...

  7. 【BZOJ1019】[SHOI2008]汉诺塔(数论,搜索)

    [BZOJ1019][SHOI2008]汉诺塔(数论,搜索) 题面 BZOJ 洛谷 题解 首先汉诺塔问题的递推式我们大力猜想一下一定会是形如\(f_i=kf_{i-1}+b\)的形式. 这个鬼玩意不好 ...

  8. bzoj千题计划109:bzoj1019: [SHOI2008]汉诺塔

    http://www.lydsy.com/JudgeOnline/problem.php?id=1019 题目中问步骤数,没说最少 可以大胆猜测移动方案唯一 (真的是唯一但不会证) 设f[i][j] ...

  9. 【BZOJ 1019】 1019: [SHOI2008]汉诺塔 (DP?)

    1019: [SHOI2008]汉诺塔 Description 汉诺塔由三根柱子(分别用A B C表示)和n个大小互不相同的空心盘子组成.一开始n个盘子都摞在柱子A上,大的在下面,小的在上面,形成了一 ...

随机推荐

  1. SQL基础语句汇总

    连接数据库 1 mysql -h10.20.66.32 -uroot -p123456 -h后面是mysqlServer所在地址,-u后面是用户名,-p后面是密码 查看数据库 1 show datab ...

  2. 小程序navigateTo和redirectTo的使用

    最近公司商城项目,有个小问题,就是在商品详情页>购物车页>确认下单页>支付成功和取消支付都会前往订单详情页.当时我没想这么多就全部跳转都用了navigateTo,这样做的话,第一个问 ...

  3. JS - 给String.prototype添加replaceAll方法

    String.prototype.replaceAll = function (targetStr, newStr) {  var sourceStr = this.valueOf();  while ...

  4. mysql 创建用户、授权、修改密码

    以下操作都要在mysql所在机器操作 一.创建用户 CREATE USER 'dog'@'localhost' IDENTIFIED BY '123456'; 或 insert into mysql. ...

  5. 笔记-python-多线程-深入-1

    笔记-python-多线程-深入-1 1.      线程池 1.1.    线程池:控制同时存在的线程数量 threading没有线程池,只能自己控制线程数量. 基本有两种方式: 每间隔一段时间创建 ...

  6. 笔记-爬虫-模拟登录github

    笔记-模拟登录github 1.      模拟登录github 1.1.    环境准备 安装/升级requests 2.20.0 pip install --upgrade requests pi ...

  7. 使用Windows Live Writer写文章时不要用360清除垃圾

    ref:http://www.zhengsiwei.com/write-an-article-to-use-windows-live-writer-dont-use-360-to-remove-rub ...

  8. Hadoop(初始Hadoop)

    Hadoop核心组件 1.Hadoop生态系统 Hadoop具有以下特性: 方便:Hadoop运行在由一般商用机器构成的大型集群上,或者云计算服务上 健壮:Hadoop致力于在一般商用硬件上运行,其架 ...

  9. 关于C、内存、栈的一些杂谈

    c的程序要手动管理内存的,所有的数据(结构)都可以分为两种存储方式,连续存储,顾名思义申请一片连续的内存以供使用(数组.结构体.共用体.栈.队列):非连续存储,顾名思义断断续续的的存储,那有一点这有一 ...

  10. 一、MySQL数据库之简介和安装

    一.基础部分 1.数据库是简介     之前所学,数据要永久保存,比如用户注册的用户信息,都是保存于文件中,而文件只能存在于某一台机器上. 如果我们不考虑从文件中读取数据的效率问题,并且假设我们的程序 ...