漢諾塔
題意:三根柱子,每次移動距離無限制,一次移動一個圓盤,問將所有圓盤從按大小順序移動到最少需要多少步。
思路:因爲這裏不需要小圓盤始終在大圓盤上面,所以
設移動個圓盤的方案爲,顯然先將個圓盤移動到上需要步。
然後最後一個圓盤移動到需要步,然後再將個圓盤移動到需要步。
所以.
漢諾塔1
題意:三根柱子,每次移動距離無限制,一次移動一個圓盤,要求小圓盤始終在大圓盤上面,問將所有圓盤從按大小順序移動到最少需要多少步。
思路:設移動個圓盤的方案爲,顯然先將個圓盤移動到上需要 步,然後最後一個圓盤移動到需要步,然後再將個圓盤移動到需要步。所以 。(另外遞歸或者打表都可以找到規律)
遞歸代碼:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
#define mst(a) memset(a,0,sizeof a)
int cnt=0;
void fun(int n,char a,char b,char c){
if(n==1){
printf("第%d次移動:將%d號圓盤從 %c 移動到 %c\n",++cnt,1,a,c);
return;
}
fun(n-1,a,c,b);
printf("第%d次移動:將%d號圓盤從 %c 移動到 %c\n",++cnt,n,a,c);
fun(n-1,b,a,c);
}
int main(){
int n;
char a='a',b='b',c='c';
while(~scanf("%d",&n)){
cnt=0;
fun(n,a,b,c);
printf("總共移動次數:%d\n",cnt);
}
return 0;
}
漢諾塔2
題意:三根柱子,每次移動到相鄰柱子,一次移動一個圓盤,要求小圓盤始終在大圓盤上面,問將所有圓盤從按大小順序移動到最少需要多少步。
思路:設移動個圓盤的方案爲,先將上面個圓盤移動到上需要 步,然後最後一個圓盤移動到需要步,然後再將個圓盤移動到需要步,再將最後一個圓盤移動到需要一步,再將個圓盤移動到需要步,所以
漢諾塔3
題意:四根柱子,每次移動距離無限制,一次移動一個圓盤,要求小圓盤始終在大圓盤上面,問將所有圓盤從按大小順序移動到最少需要多少步。
思路:假設以爲輔助柱子,從移動個圓盤到的方案記爲.然後將剩下的個柱子利用輔助柱子從移動到的方案爲(三柱漢諾塔)。
再將個圓盤以爲輔助柱子移動到的方案爲.
所以
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
#define mst(a) memset(a,0,sizeof a)
ll f[N];
int n;
int main(){
f[1]=1;
for(int i=2;i<=64;i++){
f[i]=1e18;
for(int r=1;r<=i;r++){
f[i]=min(f[i]*1.0,2*f[i-r]+pow(2,r)-1);
}
}
while(~scanf("%d",&n))
printf("%lld\n",f[n]);
return 0;
}