BZOJ1019 汉诺塔

定义f[i][j]为将i柱上的j个盘挪走(按优先级)的步数

p[i][j]为将i柱上的j个盘按优先级最先挪至何处

首先考虑一定p[i][j]!=i

设初始为a柱,p[i][j-1]为b柱

考虑两种情况,已经挪走的这j-1个盘如果挪到区别于这两柱的c柱,那么就是经典的汉诺塔,所以只能动底盘到c柱,其他的移向c柱

如果挪回a柱,那么就要先把底盘挪到c,然后把b柱的挪到a柱,然后把底盘的挪到b柱,此时a柱的优先级还是b柱,所以继续移向b柱

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 ll f[4][35];char s[3];
 5 int p[4][35],x[10],y[10],n;
 6 int main()
 7 {
 8     scanf("%d",&n);
 9     for(int i=1;i<=6;++i)
10     {
11         scanf("%s",s);
12         x[i]=s[0]-'A'+1,y[i]=s[1]-'A'+1;
13     }
14     for(int i=6;i>=1;--i)p[x[i]][1]=y[i];
15     for(int i=1;i<=3;++i)f[i][1]=1ll;
16     for(int i=2;i<=n;++i)
17     {
18         for(int a=1;a<=3;++a)
19         {
20             int b=p[a][i-1],c=6-a-b;
21             if(p[b][i-1]==c)
22             {
23                 f[a][i]=f[a][i-1]+1+f[b][i-1];
24                 p[a][i]=c;
25             }
26             else if(p[b][i-1]==a)
27             {
28                 f[a][i]=f[a][i-1]+1+f[b][i-1]+1+f[a][i-1];
29                 p[a][i]=b;
30             }
31         }
32     }
33     printf("%lld\n",f[1][n]);
34     return 0;
35 }

 

posted @ 2018-01-19 10:37  大奕哥&VANE  阅读(192)  评论(0编辑  收藏  举报