【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的优先级大的话,那就 ...
随机推荐
- poj 3020 最短路径覆盖 Antenna Placement
Antenna Placement Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7329 Accepted: 3635 ...
- 同时运行多个scrapy爬虫的几种方法(自定义scrapy项目命令)
试想一下,前面做的实验和例子都只有一个spider.然而,现实的开发的爬虫肯定不止一个.既然这样,那么就会有如下几个问题:1.在同一个项目中怎么创建多个爬虫的呢?2.多个爬虫的时候是怎么将他们运行起来 ...
- Java for LeetCode 148 Sort List
Sort a linked list in O(n log n) time using constant space complexity. 解题思路: 归并排序.快速排序.堆排序都是O(n log ...
- Greedy:Packets(POJ 1017)
装箱问题1.0 题目大意:就是一个工厂制造的产品都是正方形的,有1*1,2*2,3*3,4*4,5*5,6*6,高度都是h,现在要包装这些物品,只能用6*6*h的包装去装,问你怎么装才能使箱子打到最小 ...
- codeforces A. Sereja and Bottles 解题报告
题目链接:http://codeforces.com/problemset/problem/315/A 题目意思:有n个soda bottles,随后给出这n个soda bottles的信息.已知第 ...
- Light OJ 1393 Crazy Calendar (尼姆博弈)
C - Crazy Calendar Time Limit:4000MS Memory Limit:32768KB 64bit IO Format:%lld & %llu Su ...
- 使用__declspec(export)导出C++类到DLL
使用举例: // File: SimpleDLLClass.h#ifdef SIMPLEDLL_EXPORT //在DLL工程属性-c/c++-预处理器-预处理器定义中添加此宏定义#define DL ...
- excel数据导入SQLite数据库
参考:http://blog.baisi.net/?110653/viewspace-6725 1.excel表中最上面一行的字段名留着,留着以后导入的时候对应. 2.保存成csv格式,在选择文件类型 ...
- js iframe onload &line-height浏览器兼容问题
1.IE iframe onload事件 在IE下给iframe添加onload事件经常无效,因为在IE下它最多只能被激活一次,而且无论你有多少个iframe,被激活的也只能是最后一个的.可以用下面的 ...
- Android_adb shell am/pm使用
转自:http://blog.sina.com.cn/s/blog_51335a0001017ux5.html adb shell am instrument [options] <COMP ...