http://www.lydsy.com/JudgeOnline/problem.php?id=1019

题意:汉诺塔规则,只不过盘子n<=30,终点在B柱或C柱,每一次移动要遵守规则:1、小的不能放在大的下边。2、之前移动过的圆盘不能再次移动。3、如果有多个可移动圆盘那么按照题目所给的优先级移动。

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <cmath>
  4. #include <string>
  5. #include <iostream>
  6. #include <algorithm>
  7. #include <queue>
  8. #include <set>
  9. #include <map>
  10. #include <sstream>
  11. using namespace std;
  12. typedef long long ll;
  13. #define pb push_back
  14. #define rep(i, n) for(int i=0; i<(n); ++i)
  15. #define for1(i,a,n) for(int i=(a);i<=(n);++i)
  16. #define for2(i,a,n) for(int i=(a);i<(n);++i)
  17. #define for3(i,a,n) for(int i=(a);i>=(n);--i)
  18. #define for4(i,a,n) for(int i=(a);i>(n);--i)
  19. #define CC(i,a) memset(i,a,sizeof(i))
  20. #define read(a) a=getint()
  21. #define print(a) printf("%d", a)
  22. #define dbg(x) cout << (#x) << " = " << (x) << endl
  23. #define error(x) (!(x)?puts("error"):0)
  24. #define rdm(x, i) for(int i=ihead[x]; i; i=e[i].next)
  25. inline int getint() { static int r, k; r=0,k=1; static char c; c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; }
  26.  
  27. const int N=33;
  28. int n;
  29. int m[3][3], g[3][N];
  30. ll f[3][N];
  31. int main() {
  32. read(n);
  33. char s[4];
  34. rep(i, 6) {
  35. scanf("%s", s);
  36. int x=s[0]-'A', y=s[1]-'A';
  37. m[x][y]=i;
  38. }
  39. f[0][1]=f[1][1]=f[2][1]=1;
  40. g[0][1]=m[0][1]<m[0][2]?1:2;
  41. g[1][1]=m[1][0]<m[1][2]?0:2;
  42. g[2][1]=m[2][0]<m[2][1]?0:1;
  43. for1(j, 2, n) {
  44. rep(i, 3) {
  45. ll &ans=f[i][j];
  46. ans=f[i][j-1]+1;
  47. int now=3-g[i][j-1]-i;
  48. int nxt=g[i][j-1];
  49. while(g[nxt][j-1]!=now || now==i) {
  50. ans+=f[nxt][j-1]+1;
  51. now=3-g[nxt][j-1]-now;
  52. nxt=g[nxt][j-1];
  53. }
  54. if(g[nxt][j-1]==now) ans+=f[nxt][j-1];
  55. g[i][j]=now;
  56. }
  57. }
  58. printf("%lld\n", f[0][n]);
  59. return 0;
  60. }

  


一开始想到是递推,发现了几个性质后...还是没想到怎么推QAQ,然后去翻题解...

看到只要设两个状态就行了...于是就自己yy...还好yy出来了...

容易发现:要想将圆盘i移动,那么在i上边的圆盘i-1~1一定移动到了另一个一样的柱上,而且,下一步一定是i移动到不同于上边两个的柱子上(优先级无用)。

然后又容易发现:将圆盘i移动到了该移动的位置上,现在要将剩余的i-1~1的圆盘放回到i的上边,就模拟就行辣~

所以设状态f[i,j]表示当前在i柱,要移动j到另一个柱上,g[i, j]表示移动到的另一个柱的编号。然后随便推推就行辣

然后不知道为啥,我之前写的i移动的位置没有特判和i相等也过了QAQ......

【BZOJ】1019: [SHOI2008]汉诺塔的更多相关文章

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

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

  2. BZOJ 1019: [SHOI2008]汉诺塔

    Description 一个汉诺塔,给出了移动的优先顺序,问从A移到按照规则移到另一个柱子上的最少步数. 规则:小的在大的上面,每次不能移动上一次移动的,选择可行的优先级最高的. Sol DP. 倒着 ...

  3. BZOJ 1019 :[SHOI2008]汉诺塔(递推)

    好吧蒟蒻还是看题解的 其实看到汉诺塔就该想到是递推了 设f[i][j]表示i个在j杆转移到另一个杆的次数 g[i][j]表示i个在j杆转移到那个杆上 可得 f[i][j]=f[i-1][j]+1+f[ ...

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

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

  5. 1019: [SHOI2008]汉诺塔

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

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

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

  7. bzoj1019 [SHOI2008]汉诺塔

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

  8. 【bzoj1019】[SHOI2008]汉诺塔

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

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

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

随机推荐

  1. 极客教学:如何使用树莓派击落&劫持无人机

    本教程的目的是帮助大家理解如何研究未受保护的无线通信的安全风险所在,同时我们希望大家不要对技术进行滥用.我们这里采用的例子是一个流行的无人机模型:Parrot AR.Drone 2.0. 四轴无人机能 ...

  2. Python的getattr()

    Python的getattr(),setattr(),delattr(),hasattr() getattr()函数是Python自省的核心函数,具体使用大体如下: 获取对象引用getattrGeta ...

  3. ssh: connect to host localhost port 22: Connection refused 问题

    错误原因:1.sshd 未安装2.sshd 未启动 3.防火墙 4需重新启动ssh 服务 解决方法:1.确定安装sshd: $ sudo apt-get install openssh-server ...

  4. 【转】mysql 触发器实现两个表的数据同步

    mysql通过触发器实现两个表的同步 目前,在本地测试成功. 假设本地的两个数据库a和b,a下有表table1(id, val) b下有表table2(id, val) 假设希望当table1中数据更 ...

  5. process vs thread

    process vs thread http://blog.csdn.net/mishifangxiangdefeng/article/details/7588727 6.进程与线程的区别:系统调度是 ...

  6. codeforces B. Eight Point Sets 解题报告

    题目链接:http://codeforces.com/problemset/problem/334/B 一开始看到题目,有点怯,理解了题目后,其实并不难.这句话是突破口 three distinct ...

  7. 【数据结构】hanoi

    #include<stdio.h> void hanoi(int n,char x,char y,char z) { ; ) printf("%d. Move disk %d f ...

  8. 在eclipse中打开项目所在的目录

    展开如下菜单: Run ---- External Tools ---- External Tools Configurations   在 program 下面新建一个工具 program--右击- ...

  9. ping: unknown host www.baidu.com

    #注意有很多的DNS服务器 为了防止DDOS攻击 所以都禁止PING [root@86 ~]# ping -c 2 www.baidu.com ping: unknown host www.baidu ...

  10. Feed系统架构资料收集

    完全用nosql轻松打造千万级数据量的微博系统 微博feed系统的push和pull模式和时间分区拉模式架构探讨 关于如何构建一个微博型广播 关于如何构建一个微博型广播2 用 mongodb 储存多态 ...