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
AB BC CA BA CB AC
Sample Output
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]汉诺塔的更多相关文章
-
bzoj千题计划109:bzoj1019: [SHOI2008]汉诺塔
http://www.lydsy.com/JudgeOnline/problem.php?id=1019 题目中问步骤数,没说最少 可以大胆猜测移动方案唯一 (真的是唯一但不会证) 设f[i][j] ...
-
bzoj1019: [SHOI2008]汉诺塔(动态规划)
1019: [SHOI2008]汉诺塔 题目:传送门 简要题意: 和经典的汉诺塔问题区别不大,但是题目规定了一个移动时的优先级: 如果当前要从A柱子移动,但是A到C的优先级比A到B的优先级大的话,那就 ...
-
[bzoj1019][SHOI2008]汉诺塔 (动态规划)
Description 汉诺塔由三根柱子(分别用A B C表示)和n个大小互不相同的空心盘子组成.一开始n个盘子都摞在柱子A上,大的在下面,小的在上面,形成了一个塔状的锥形体. 对汉诺塔的一次合法的操 ...
-
【BZOJ1019】[SHOI2008]汉诺塔(数论,搜索)
[BZOJ1019][SHOI2008]汉诺塔(数论,搜索) 题面 BZOJ 洛谷 题解 首先汉诺塔问题的递推式我们大力猜想一下一定会是形如\(f_i=kf_{i-1}+b\)的形式. 这个鬼玩意不好 ...
-
bzoj1019 / P4285 [SHOI2008]汉诺塔
P4285 [SHOI2008]汉诺塔 递推 题目给出了优先级,那么走法是唯一的. 我们用$0,1,2$代表$A,B,C$三个柱子 设$g[i][x]$为第$x$根柱子上的$i$个盘子,经过演变后最终 ...
-
【bzoj1019】[SHOI2008]汉诺塔
1019: [SHOI2008]汉诺塔 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 1427 Solved: 872[Submit][Status] ...
-
BZOJ1019 汉诺塔/洛谷P4285 [SHOI2008]汉诺塔
汉诺塔(BZOJ) P4285 [SHOI2008]汉诺塔 居然是省选题,还是DP!(我的DP菜得要死,碰见就丢分) 冥思苦想了1h+ \(\to\) ?! 就是普通的hanoi NOI or HNO ...
-
1019: [SHOI2008]汉诺塔
1019: [SHOI2008]汉诺塔 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 1495 Solved: 916[Submit][Status] ...
-
【bzoj1019】汉诺塔
[bzoj1019]汉诺塔 题意 传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1019 分析 思路1:待定系数+解方程 设\(f[n]\)为 ...
随机推荐
-
[原创]kali linux下破解wifi密码以及局域网渗透
无线破解是进行无线渗透的第一步.破解无线目前只有两种方法:抓包.跑pin. 破解无线方法一:抓包.我是在kali linux下进行的. 将无线网卡的模式调为监听模式. airmon-ng start ...
-
区分PC端与移动端代码,涵盖C#、JS、JQuery、webconfig
1)C#区分PC端或移动端 using System.Text.RegularExpressions string u = Request.ServerVariables["HTTP_USE ...
-
第 14 章 CSS 颜色与度量单位
学习要点: 1.颜色表方案 2.度量单位 主讲教师:李炎恢 本章主要探讨 HTML5 中 CSS 颜色和度量单位等问题,包括颜色的选取方式.相对长度和绝对长度等. 一.颜色表方案 颜色的表现形式主要有 ...
-
框架基础——全面解析Java注解
为什么学习注解? 学习注解有什么好处? 学完能做什么? 答:1. 能够读懂别人写的代码,特别是框架相关的代码: 2. 让编程更加简洁,代码更加清晰: 3. 让别人高看一眼. spring.mybati ...
-
.NET在后置代码中输入JS提示语句(背景不会变白)
来源:http://niunan.iteye.com/blog/248256 Page.ClientScript.RegisterStartupScript(Page.GetType(), " ...
-
SharePoint安全 - 攻破SharePoint(黑客工具介绍)
博客地址 http://blog.csdn.net/foxdave SharePoint的安全性很高,这是我们潜意识里的第一印象,所以具体的安全性体现在哪并没仔细研究过.但是事实上确实没有绝对安全的东 ...
-
hdu 1885 Key Task
题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=1885 Key Task Description The Czech Technical Univers ...
-
AEAI HR薪资汇总功能介绍
1 概述 人力资源系统是一个公司重要的管理工具,而薪资管理是人力资源管理系统中最为核心的功能模块,它包括不同员工的薪资标准.薪资的组成部分,例如:对奖惩管理.保险和年假等员工必备的福利待遇进行统一管理 ...
-
centos6.5下oracle11g开机自动启动方法一
转裁于 方法一 https://blog.csdn.net/wx5040257/article/details/77875690 方法二 https://blog.csdn.net/wx504025 ...
-
图片在线处理 webp!
之前处理图片的方式是,小图标通过gulp配置的spritesmith雪碧图方式,.png会先用ps工具转成.jpg,然后jpg太大则用在线压缩工具来进行压缩(另外gulp系列的gulp-imagemi ...