1019: [SHOI2008]汉诺塔

Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 1427  Solved: 872
[Submit][Status][Discuss]

Description

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

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

Input

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

Output

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

Sample Input

3
AB BC CA BA CB AC

Sample Output

7
 
 
【题解】
这道题没有看题解,纯自己想出来的,写完之后,感觉智商提高了不少。
 
首先关于汉诺塔问题,如果策略不变,那么一定满足一个线性递推关系:f[i]=f[i-1]*a+b(证明自己yy)
 
那么我们就可以先模拟出f[1],f[2],f[3]的值,求出a=(f[3]-f[2])/(f[2]-f[1]) ,  b=f[2]-a*f[1]
 
然后线性递推即可,别忘了用long long
 
  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<cstdlib>
  5. #include<cmath>
  6. #include<ctime>
  7. #include<algorithm>
  8. #include<algorithm>
  9. using namespace std;
  10. #define INF 99999999
  11. char ch[][];
  12. int n,stack[][],top[];
  13. long long f[];
  14. inline int read()
  15. {
  16. int x=,f=; char ch=getchar();
  17. while(!isdigit(ch)) {if(ch=='-') f=-; ch=getchar();}
  18. while(isdigit(ch)) {x=x*+ch-''; ch=getchar();}
  19. return x*f;
  20. }
  21. bool check(){return (!top[]&&!top[])||(!top[]&&!top[]);}
  22. void work(int x)
  23. {
  24. memset(stack,,sizeof(stack));
  25. memset(top,,sizeof(top));
  26. for(int i=x;i;i--) stack[][++top[]]=i;
  27. int last=;
  28. stack[][]=stack[][]=stack[][]=INF;
  29. while(!check())
  30. {
  31. for(int i=;i<;i++)
  32. {
  33. int xx=ch[i][]-'A'+,yy=ch[i][]-'A'+;
  34. if(stack[xx][top[xx]]<stack[yy][top[yy]]&&stack[xx][top[xx]]!=last)
  35. {
  36. stack[yy][++top[yy]]=stack[xx][top[xx]];
  37. last=stack[xx][top[xx]]; top[xx]--;
  38. break;
  39. }
  40. }
  41. f[x]++;
  42. }
  43. }
  44. int main()
  45. {
  46. //freopen("cin.in","r",stdin);
  47. //freopen("cout.out","w",stdout);
  48. n=read();
  49. for(int i=;i<;i++) scanf("%c%c ",&ch[i][],&ch[i][]);
  50. f[]=;
  51. work();
  52. work();
  53. int a=(f[]-f[])/(f[]-f[]),b=f[]-a*f[];
  54. for(int i=;i<=n;i++) f[i]=f[i-]*a+b;
  55. printf("%lld\n",f[n]);
  56. return ;
  57. }
 
 

【bzoj1019】[SHOI2008]汉诺塔的更多相关文章

  1. bzoj1019 [SHOI2008]汉诺塔

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

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

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

  3. bzoj1019: [SHOI2008]汉诺塔(动态规划)

    1019: [SHOI2008]汉诺塔 题目:传送门 简要题意: 和经典的汉诺塔问题区别不大,但是题目规定了一个移动时的优先级: 如果当前要从A柱子移动,但是A到C的优先级比A到B的优先级大的话,那就 ...

  4. [bzoj1019][SHOI2008]汉诺塔 (动态规划)

    Description 汉诺塔由三根柱子(分别用A B C表示)和n个大小互不相同的空心盘子组成.一开始n个盘子都摞在柱子A上,大的在下面,小的在上面,形成了一个塔状的锥形体. 对汉诺塔的一次合法的操 ...

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

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

  6. bzoj1019 / P4285 [SHOI2008]汉诺塔

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

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

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

  8. 1019: [SHOI2008]汉诺塔

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

  9. 【bzoj1019】汉诺塔

    [bzoj1019]汉诺塔 题意 传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1019 分析 思路1:待定系数+解方程 设\(f[n]\)为 ...

随机推荐

  1. 毕业生、程序猿转岗该如何选择Java、大数据和VR?答案在这里!

    许久不见的朋友请我吃饭,期间给我介绍他一个弟弟,说明年要毕业了,还不知道找啥工作,说有培训机构让他学VR.大数据什么的,不知道前景咋样,想咨询一下我.相信很多朋友面临毕业,都不知道该从事哪个行业,自己 ...

  2. 前端之jQuery02

    文档操作 重点:创建标签,jQuery里面没有这个方法 内部(子标签) 添加到指定元素内部后面 $(A).append(B): // B作为A的最后一个儿子元素:(把B追加到A) $(A).appen ...

  3. (三十八)js之柯里化

    先给大家介绍什么是柯里化与反柯里化 百度翻译: 在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的 ...

  4. MyEclipse2014安装操作步骤+破解

    第一步 第二步 第三步 第四步 第五步 第六步 破解操作步骤 1.安装完成 MyEclipse2014(适用于 2013 等版本)后,不要打开软件.解压破解文件压缩包,得到一下文件列表:双击 run. ...

  5. python学习-实现用户密码登录,输错三次锁定

    作业需求: 输入用户名密码 认证成功后显示欢迎信息 输错三次后锁定 实现思路: 判断用户是否在黑名单,若在黑名单,则将用户锁定 判断用户是否存在,若不存在,提示用户不存在 若用户存在,判断登录密码是否 ...

  6. TypeError: parse() got an unexpected keyword argument 'transport_encoding' 安装tensor后报错

    TypeError: parse() got an unexpected keyword argument 'transport_encoding' 巨蛋疼,出这个问题后,老夫真是醉了,mmp,最后在 ...

  7. 1138. Postorder Traversal (25)

    Suppose that all the keys in a binary tree are distinct positive integers. Given the preorder and in ...

  8. 《DSP using MATLAB》示例Example7.17

    代码: M = 40; alpha = (M-1)/2; l = 0:M-1; wl = (2*pi/M)*l; T1 = 0.109021; T2 = 0.59417456; Hrs = [zero ...

  9. MAC OS X常用命令总结2

    1. dir:显示某个目录下的子目录与文件. 格式:dir [x:] [Path] [filename][ parameter] 参数解释: /a      显示所有文件夹与文件. /p     分页 ...

  10. mysql存入GBK编码字段信息

    set @moneyStr=BASE64_ENCODE(CONVERT(CONCAT('线上报名且已交费',money,'元') using GBK));