【BZOJ】1019: [SHOI2008]汉诺塔
http://www.lydsy.com/JudgeOnline/problem.php?id=1019
题意:汉诺塔规则,只不过盘子n<=30,终点在B柱或C柱,每一次移动要遵守规则:1、小的不能放在大的下边。2、之前移动过的圆盘不能再次移动。3、如果有多个可移动圆盘那么按照题目所给的优先级移动。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <iostream>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
#include <sstream>
using namespace std;
typedef long long ll;
#define pb push_back
#define rep(i, n) for(int i=0; i<(n); ++i)
#define for1(i,a,n) for(int i=(a);i<=(n);++i)
#define for2(i,a,n) for(int i=(a);i<(n);++i)
#define for3(i,a,n) for(int i=(a);i>=(n);--i)
#define for4(i,a,n) for(int i=(a);i>(n);--i)
#define CC(i,a) memset(i,a,sizeof(i))
#define read(a) a=getint()
#define print(a) printf("%d", a)
#define dbg(x) cout << (#x) << " = " << (x) << endl
#define error(x) (!(x)?puts("error"):0)
#define rdm(x, i) for(int i=ihead[x]; i; i=e[i].next)
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; } const int N=33;
int n;
int m[3][3], g[3][N];
ll f[3][N];
int main() {
read(n);
char s[4];
rep(i, 6) {
scanf("%s", s);
int x=s[0]-'A', y=s[1]-'A';
m[x][y]=i;
}
f[0][1]=f[1][1]=f[2][1]=1;
g[0][1]=m[0][1]<m[0][2]?1:2;
g[1][1]=m[1][0]<m[1][2]?0:2;
g[2][1]=m[2][0]<m[2][1]?0:1;
for1(j, 2, n) {
rep(i, 3) {
ll &ans=f[i][j];
ans=f[i][j-1]+1;
int now=3-g[i][j-1]-i;
int nxt=g[i][j-1];
while(g[nxt][j-1]!=now || now==i) {
ans+=f[nxt][j-1]+1;
now=3-g[nxt][j-1]-now;
nxt=g[nxt][j-1];
}
if(g[nxt][j-1]==now) ans+=f[nxt][j-1];
g[i][j]=now;
}
}
printf("%lld\n", f[0][n]);
return 0;
}
一开始想到是递推,发现了几个性质后...还是没想到怎么推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]汉诺塔的更多相关文章
- BZOJ 1019: [SHOI2008]汉诺塔( dp )
dp(x, y)表示第x根柱子上y个盘子移开后到哪根柱子以及花费步数..然后根据汉诺塔原理去转移... ------------------------------------------------ ...
- BZOJ 1019: [SHOI2008]汉诺塔
Description 一个汉诺塔,给出了移动的优先顺序,问从A移到按照规则移到另一个柱子上的最少步数. 规则:小的在大的上面,每次不能移动上一次移动的,选择可行的优先级最高的. Sol DP. 倒着 ...
- BZOJ 1019 :[SHOI2008]汉诺塔(递推)
好吧蒟蒻还是看题解的 其实看到汉诺塔就该想到是递推了 设f[i][j]表示i个在j杆转移到另一个杆的次数 g[i][j]表示i个在j杆转移到那个杆上 可得 f[i][j]=f[i-1][j]+1+f[ ...
- 【BZOJ 1019】 1019: [SHOI2008]汉诺塔 (DP?)
1019: [SHOI2008]汉诺塔 Description 汉诺塔由三根柱子(分别用A B C表示)和n个大小互不相同的空心盘子组成.一开始n个盘子都摞在柱子A上,大的在下面,小的在上面,形成了一 ...
- 1019: [SHOI2008]汉诺塔
1019: [SHOI2008]汉诺塔 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 1495 Solved: 916[Submit][Status] ...
- bzoj千题计划109:bzoj1019: [SHOI2008]汉诺塔
http://www.lydsy.com/JudgeOnline/problem.php?id=1019 题目中问步骤数,没说最少 可以大胆猜测移动方案唯一 (真的是唯一但不会证) 设f[i][j] ...
- bzoj1019 [SHOI2008]汉诺塔
1019: [SHOI2008]汉诺塔 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 1030 Solved: 638[Submit][Status] ...
- 【bzoj1019】[SHOI2008]汉诺塔
1019: [SHOI2008]汉诺塔 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 1427 Solved: 872[Submit][Status] ...
- bzoj1019: [SHOI2008]汉诺塔(动态规划)
1019: [SHOI2008]汉诺塔 题目:传送门 简要题意: 和经典的汉诺塔问题区别不大,但是题目规定了一个移动时的优先级: 如果当前要从A柱子移动,但是A到C的优先级比A到B的优先级大的话,那就 ...
随机推荐
- 深度学习入门教程UFLDL学习实验笔记二:使用向量化对MNIST数据集做稀疏自编码
今天来做UFLDL的第二个实验,向量化.我们都知道,在matlab里面基本上如果使用for循环,程序是会慢的一逼的(可以说基本就运行不下去)所以在这呢,我们需要对程序进行向量化的处理,所谓向量化就是将 ...
- Linux 命令行生成随机密码的十种方法
Linux操作系统的一大优点是对于同样一件事情,你可以使用高达数百种方法来实现它.例如,你可以通过数十种方法来生成随机密码.本文将介绍生成随机密码的十种方法.这些方法均收集于Command-Line ...
- 查看现有运行的linux服务器有多少内存条
i161 admin # ssh 192.168.5.209 dmidecode | grep 'Ending Address' -B1 -A2 Starting Address: 0x0000 ...
- CentOS 关闭蜂鸣器声音
也许你会遇到像我这样的情况,每次使用Linux终端,当听到发出“嘀嘀”的声音时候,我都有种把我的机箱拆掉把那个内置的蜂鸣装置拽下来的冲动.按 Tab时候“嘀嘀”,按空格时候“嘀嘀”,每个在vi中错误的 ...
- Missing Ranges & Summary Ranges
Missing Ranges Given a sorted integer array where the range of elements are [lower, upper] inclusive ...
- Android 中的异步下载
网上提到最多的就是利用AsyncTask进行异步下载,用android-async-http第三方库的也比较多.这里写点注意事项. 先说说android-async-http,这个库发送请求利用thr ...
- sockaddr struct 类型重定义
windows.h和winsock2.h有类型重定义我是知道的,本来就一个库来说没问题,把winsock2放到windows.h前或先定义WIN32_LEAN_AND_MEAN都能解决问题但现的出了问 ...
- BestCoder12 1001.So easy(hdu 5058) 解题报告
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5058 (格式有点问题,为了方便阅读---整个复制下来吧) 题目意思:给出两个长度都为 n 的集合你,问 ...
- IE的安全性设定增加“我的电脑”的安全性设定
HKEY_CURRE-NT_USER\Software\Microsoft\Windows\CurrentVersion\InternetSettings\Zones\,在右边窗口中找到DWORD值“ ...
- Mysql常用函数列举
1,HEX(),十六进制转化;eg:select HEX('mysql'); select X'6D7973716C'; 2,bit_count(),计算二进制数中包含1的个数;bit_or(),对两 ...