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

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

-----------------------------------------------------------------------

#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

#define X(o) o.pos
#define Y(o) o.w
typedef long long ll;

const int maxn = 39;

struct node {
int pos; ll w;
} dp[3][maxn];

int N, Move[6][2];

int main() {
scanf("%d", &N);
for(int i = 0; i < 6; i++) {
char s[4]; scanf("%s", s);
Move[i][0] = s[0] - 'A';
Move[i][1] = s[1] - 'A';
}
for(int i = 0; i < 3; i++)
for(int j = 0; j < 6; j++) if(Move[j][0] == i) {
X(dp[i][1]) = Move[j][1];
Y(dp[i][1]) = 1;
break;
}
for(int y = 2; y <= N; y++)
for(int x = 0; x < 3; x++) {
Y(dp[x][y]) = Y(dp[x][y - 1]) + 1;
if(X(dp[X(dp[x][y - 1])][y - 1]) != x) {
X(dp[x][y]) = 3 - x - X(dp[x][y - 1]);
Y(dp[x][y]) += Y(dp[X(dp[x][y - 1])][y - 1]);
} else {
(Y(dp[x][y]) <<= 1) += Y(dp[X(dp[x][y - 1])][y - 1]);
X(dp[x][y]) = X(dp[x][y - 1]);
}
}
printf("%lld\n", Y(dp[0][N]));
return 0;
}

-----------------------------------------------------------------------

## 1019: [SHOI2008]汉诺塔

Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 1119  Solved: 685
[Submit][Status][Discuss]

## Sample Input

3
AB BC CA BA CB AC

7

## Source

posted @ 2015-11-03 11:08  JSZX11556  阅读(205)  评论(0编辑  收藏