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 }
生命中真正重要的不是你遭遇了什么,而是你记住了哪些事,又是如何铭记的。