1019: [SHOI2008]汉诺塔

Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 1030  Solved: 638
[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

HINT

 

Source

题意:按一定规则行动,问如此行动,多少步后会将第一柱上的盘子全部移动到另一柱上

分析:

一、我们可以Dp

Dp[i][x]表示前 i 个盘子一开始放在 第x柱上,用了多少步可以移动到另一柱上

P[i][x]表示前 i 个盘子一开始放在 第x柱上,按题目所给策略移动,用了Dp[i][x]步后移动到了 P[i][x] 根柱上

那么转移很明显可以从i转移到i+1

用y表示p[i][x],z表示第 i+1个盘子将要去的柱子

那么因为前 i 个盘子移到了 y,盘子又不能连续移动,大盘不能压着小盘, 所以第 z个柱子一定是空的,且只能移动第 i+1个盘子

所以这时 z = 1+2+3-x-y

移动过去后,那就要将那前i个盘子移到第i+1个盘子上面

又因为根据策略移动,所以一定数量的盘子从某根柱子上开始移动,无论第 i+1个盘子在哪,情况一定相同,所以

当 p[i][y] == z时,那么就放在上面就好,p[i+1][x] = z,Dp[i+1][x] = Dp[i][x]+1+Dp[i][y]

当 p[i][y] == x时,那么因为从x上会移到y上,又因为不能连续移动,不能压着小盘,所以下一步一定是第i+1个盘子从z移动到y,然后在将前 i 个盘子压到 第y根柱子上,所以p[i+1][x] = y,Dp[i+1][x] = Dp[i][x]+1+Dp[i][y]+1+Dp[i][x]

二、根据陈丽洁大神的找规律,用Dp[i]表示n = i 时的答案

有这样的性质

Dp[i+1] = a*Dp[i]+b

a,b根据策略的不同决定

暴力算出前三个答案,待定系数法求出a,b

。。。至于证明,不会。。。

不过根据Dp的结果,的确是有这个性质

综上所述,本题得解

只提供第一种解法

 #include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <deque>
#include <vector>
#include <queue>
#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <ctime>
using namespace std;
typedef long long LL;
#define For(i, s, t) for(int i = (s); i <= (t); i++)
#define Ford(i, s, t) for(int i = (s); i >= (t); i--)
#define Rep(i, t) for(int i = (0); i < (t); i++)
#define Repn(i, t) for(int i = ((t)-1); i >= (0); i--)
#define MIT (2147483647)
#define INF (1000000001)
#define MLL (1000000000000000001LL)
#define sz(x) ((bnt) (x).size())
#define clr(x, y) memset(x, y, sizeof(x))
#define puf push_front
#define pub push_back
#define pof pop_front
#define pob pop_back
#define ft first
#define sd second
#define mk make_pair
inline void SetIO(string Name) {
string Input = Name+".in",
Output = Name+".out";
freopen(Input.c_str(), "r", stdin),
freopen(Output.c_str(), "w", stdout);
} const int N = ;
LL Dp[N][], P[N][];
int n, Go[]; inline void Input() {
scanf("%d", &n);
string S;
For(i, , ) {
cin>>S;
int a = S[]-'A'+, b = S[]-'A'+;
if(!Go[a]) Go[a] = b;
}
} inline void Solve() {
For(i, , ) Dp[][i] = , P[][i] = Go[i];
For(i, , n)
For(x, , ) {
int y = P[i-][x];
int z = ++-x-y;
Dp[i][x] = Dp[i-][x]++Dp[i-][y];
if(P[i-][y] == z) P[i][x] = z;
else Dp[i][x] += +Dp[i-][x], P[i][x] = y;
}
cout<<Dp[n][]<<endl;
} int main() {
SetIO("");
Input();
Solve();
return ;
}

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

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

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

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

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

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

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

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

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

  5. bzoj1019 / P4285 [SHOI2008]汉诺塔

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

  6. 【bzoj1019】[SHOI2008]汉诺塔

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

  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. 使用nginx的proxy_cache做网站缓存

    为什么要做web cache,我想大家最主要的是解决流量的压力.随着网站流量的提升,如果只是单台机器既处理静态文件,又处理动态脚本,显然效率很难上升,不能处理日益上涨的流量压力.与此同时某些网站的页面 ...

  2. cookie注入讲解

    我们首先还是来看看中网景论坛的最新版本"(CNKBBS2007)中网景论坛2007v5.0 "官方下载地址" http://www.cnetking.com/websys ...

  3. Java 7 的7个新特性

    1.对集合类的语言支持:(??) 2.自动资源管理: 3.改进的通用实例创建类型推断:(??) 4.数字字面量下划线支持:(√) 5.switch中使用string:(√) 6.二进制字面量:(√) ...

  4. SQL union和union all的区别

    Union因为要进行重复值扫描,所以效率低.如果合并没有刻意要删除重复行,那么就使用Union All  两个要联合的SQL语句 字段个数必须一样,而且字段类型要“相容”(一致): 如果我们需要将两个 ...

  5. Excel Sheet Column Title & Excel Sheet Column Number

    Excel Sheet Column Title Given a positive integer, return its corresponding column title as appear i ...

  6. Xenomai

    http://blog.csdn.net/robertsong2004/article/details/43889249 嵌入式系统的开发,如果对实时性要求不高,就可以使用Linux自身的实时补丁实现 ...

  7. cocos2dx3.0rc导出自定义类到lua的方法

    以前要导出c++类到lua,就得手动维护pkg文件,那简直就是噩梦,3.0以后就会感觉生活很轻松了. 转载请注明出处http://www.cnblogs.com/mrblue/p/3637910.ht ...

  8. 写了一个字符串的二维表: TSta

    STA 单元 (用到 System.SysUtils.TStringHelper): --------------------------------------------------------- ...

  9. extjs在窗体中添加搜索框

    在extjs中添加搜索框,搜索框代码如下: this.searchField = new Ext.ux.form.SearchField({            store : this.store ...

  10. JS操作DOM

    [功能:点击按钮显示表单] <html> <head> <meta http-equiv="Content-Type" content="t ...