BZOJ 1019 :[SHOI2008]汉诺塔(递推)

时间:2023-03-08 21:24:28
BZOJ 1019 :[SHOI2008]汉诺塔(递推)

好吧蒟蒻还是看题解的

其实看到汉诺塔就该想到是递推了

设f[i][j]表示i个在j杆转移到另一个杆的次数 g[i][j]表示i个在j杆转移到那个杆上

可得 f[i][j]=f[i-1][j]+1+f[i-1][g[i-1][j]] g[i][j]=6-j-g[i-1][j] (g[i-1][g[i-1][j]]==6-j-g[i-1][j]) 或 f[i][j]=f[i-1][j]+1+f[i-1][g[i-1][j]]+1+f[i-1][j] g[i][j]=g[i-1][j] (g[i-1][g[i-1][j]]=j)

CODE:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
long long f[50][4];int g[50][4];
int getint(char c){
 if (c=='A') return 1;
 if (c=='B') return 2;
 if (c=='C') return 3;
}
int main(){
 int n;
 scanf("%d",&n);
 for (int i=1;i<=6;i++){
  char c[3];
  scanf("%s",c);
  int t=getint(c[0]);
  if (!g[1][t]) g[1][t]=getint(c[1]);
 }
 f[1][1]=f[1][2]=f[1][3]=1;
 for (int i=2;i<=n;i++){
  for (int j=1;j<=3;j++){
   int y=g[i-1][j],z=6-j-g[i-1][j];;
   if (g[i-1][y]==j) {g[i][j]=g[i-1][j];f[i][j]=f[i-1][j]+1+f[i-1][y]+1+f[i-1][j];}
   else {g[i][j]=z;f[i][j]=f[i-1][j]+1+f[i-1][y];}
  }
 }
 printf("%lld",f[n][1]);
 return 0;
}