96. 奇怪的漢諾塔
阿新 • • 發佈:2022-04-03
漢諾塔問題,條件如下:
1、這裡有 \(A、B、C\) 和 \(D\) 四座塔。
2、這裡有 \(n\) 個圓盤,\(n\) 的數量是恆定的。
3、每個圓盤的尺寸都不相同。
4、所有的圓盤在開始時都堆疊在塔 \(A\) 上,且圓盤尺寸從塔頂到塔底逐漸增大。
5、我們需要將所有的圓盤都從塔 \(A\) 轉移到塔 \(D\) 上。
6、每次可以移動一個圓盤,當塔為空塔或者塔頂圓盤尺寸大於被移動圓盤時,可將圓盤移至這座塔上。
請你求出將所有圓盤從塔 \(A\) 移動到塔 \(D\),所需的最小移動次數是多少。
漢諾塔塔參考模型
輸入格式
沒有輸入
輸出格式
對於每一個整數 \(n\),輸出一個滿足條件的最小移動次數,每個結果佔一行。
資料範圍
\(1≤n≤12\)
輸入樣例:
沒有輸入
輸出樣例:
參考輸出格式
解題思路
遞迴
考慮先將上層中的 \(i\) 個盤子在四塔模式下移到 \(C\) 柱,因為這時在四塔模式下移動的次數最小,且由於是上層,不受 \(A\) 柱其他盤子的限制,然後再將剩餘的盤子在三塔模式下移到 \(D\) 柱,此時 \(C\) 柱受到限制,所以是三塔模式,最後再將 \(C\) 柱上的盤子在四塔模式下移到 \(D\) 柱,所以函式表示為 \(f[i]=min(2\times f[j],d[n-j])\),其中 \(d[i]\) 表示三塔模式下的最少移動次數
- 時間複雜度:\(O(n^2)\)
程式碼
// Problem: 奇怪的漢諾塔 // Contest: AcWing // URL: https://www.acwing.com/problem/content/description/98/ // Memory Limit: 64 MB // Time Limit: 1000 ms // // Powered by CP Editor (https://cpeditor.org) // %%%Skyqwq #include <bits/stdc++.h> //#define int long long #define help {cin.tie(NULL); cout.tie(NULL);} #define pb push_back #define fi first #define se second #define mkp make_pair using namespace std; typedef long long LL; typedef pair<int, int> PII; typedef pair<LL, LL> PLL; template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; } template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; } template <typename T> void inline read(T &x) { int f = 1; x = 0; char s = getchar(); while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); } while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar(); x *= f; } const int N=13; int d[N],f[N]; int main() { for(int i=1;i<=12;i++)d[i]=2*d[i-1]+1; memset(f,0x3f,sizeof f); f[1]=1; for(int i=1;i<=12;i++) { for(int j=1;j<=i;j++)f[i]=min(f[i],2*f[j]+d[i-j]); cout<<f[i]<<'\n'; } return 0; }