acwing奇怪的汉诺塔(汉诺四塔问题)
题目链接:https://www.acwing.com/activity/content/problem/content/330/
难度评价:中偏易
题目大意:表面意思
解题思路:转化成经典哈诺三塔实现,并用经典三塔递归公式ans=2^n-1或者是b[n]=2*b[n-1]+1;
先来求解一下三塔问题:https://acm.sdut.edu.cn/onlinejudge3/problems/1200
三塔问题已经再熟悉不过,即是先将第n个盘子移动到B柱,再将剩下的n-1个盘子移动到C柱,最后将剩下的1个盘子移动到C柱;
实现一下代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define int long long 4 #define IOS ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0); 5 int n; 6 void hanoi(int step,char a,char b,char c) 7 { 8 if(step==1) 9 { 10 printf("Move disk %d from %c to %c\n",step,a,c); 11 } 12 else{ 13 hanoi(step-1,a,c,b);//先将n-1盘子从a柱借助c柱子移动到b柱 14 printf("Move disk %d from %c to %c\n",step,a,c);//再将一个盘子从a柱移动到c柱 15 hanoi(step-1,b,a,c);//再将剩下的n-1个盘子借助a柱从b柱移动到c柱 16 } 17 } 18 signed main() 19 { 20 IOS; 21 cin>>n; 22 char a='A',b='B',c='C'; 23 hanoi(n,a,b,c); 24 return 0; 25 }
在来说哈诺四塔的问题
我们可以这样来实现,令b[n]表示在n个盘子的情况下求解三塔问题的最小步数,显而易见是b[n]=2*b[n-1]+1;
令a[n]表示n个盘子在四塔问题下的最小求解步数
先将i个盘子在四塔的模式下移动移动到B盘,再将剩下的n-i个盘子在三塔模式下移动到D盘,最后再将第i个盘子在四塔的模式下移动移动到D盘
可以实现这样的递推式:a[n]=min(a[n],a[i]*2+b[n-i]
参考代码:
1 #include<bits/stdc++.h>//hanoi四塔 2 using namespace std; 3 #define int long long 4 #define IOS ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0); 5 const int n=12; 6 const int N=50; 7 int a[N];//在四塔下的最短步数 8 int b[N];//在三塔下的最短步数 9 void hanoi() 10 { 11 b[1]=1; 12 for(int i=2;i<=n;i++) 13 { 14 b[i]=2*b[i-1]+1; 15 } 16 memset(a,0x3f,sizeof(a)); 17 a[0]=0; 18 for(int i=1;i<=n;i++) 19 { 20 for(int j=0;j<i;j++) 21 { 22 a[i]=min(a[i],2*a[j]+b[i-j]); 23 } 24 } 25 for(int i=1;i<=n;i++) 26 cout<<a[i]<<endl; 27 } 28 signed main() 29 { 30 IOS; 31 hanoi(); 32 return 0; 33 }
本文来自博客园,作者:江上舟摇,转载请注明原文链接:https://www.cnblogs.com/LQS-blog/p/16469675.html