1. 程式人生 > >bzoj1019: [SHOI2008]漢諾塔(dp)

bzoj1019: [SHOI2008]漢諾塔(dp)

++ 有一種 -- scrip bbs input www 滿足 -1

1019: [SHOI2008]漢諾塔

Time Limit: 1 Sec Memory Limit: 162 MB
Submit: 1739 Solved: 1062
[Submit][Status][Discuss]

Description

  漢諾塔由三根柱子(分別用A B C表示)和n個大小互不相同的空心盤子組成。一開始n個盤子都摞在柱子A上,
大的在下面,小的在上面,形成了一個塔狀的錐形體。

技術分享

  對漢諾塔的一次合法的操作是指:從一根柱子的最上層拿一個盤子放到另一根柱子的最上層,同時要保證被移
動的盤子一定放在比它更大的盤子上面(如果移動到空柱子上就不需要滿足這個要求)。我們可以用兩個字母來描


述一次操作:第一個字母代表起始柱子,第二個字母代表目標柱子。例如,AB就是把柱子A最上面的那個盤子移到
柱子B。漢諾塔的遊戲目標是將所有的盤子從柱子A移動到柱子B或柱子C上面。有一種非常簡潔而經典的策略可以幫
助我們完成這個遊戲。首先,在任何操作執行之前,我們以任意的次序為六種操作(AB、AC、BA、BC、CA和CB)
賦予不同的優先級,然後,我們總是選擇符合以下兩個條件的操作來移動盤子,直到所有的盤子都從柱子A移動到
另一根柱子:(1)這種操作是所有合法操作中優先級最高的;(2)這種操作所要移動的盤子不是上一次操作所移
動的那個盤子。可以證明,上述策略一定能完成漢諾塔遊戲。現在你的任務就是假設給定了每種操作的優先級,計

算按照上述策略操作漢諾塔移動所需要的步驟數。

Input

  輸入有兩行。第一行為一個整數n(1≤n≤30),代表盤子的個數。第二行是一串大寫的ABC字符,代表六種操
作的優先級,靠前的操作具有較高的優先級。每種操作都由一個空格隔開。

Output

  只需輸出一個數,這個數表示移動的次數。我們保證答案不會超過10的18次方。

Sample Input

3
AB BC CA BA CB AC

Sample Output

7
/*
如果是普通漢諾塔
操作就是將第一個柱子除底盤外的移到第二個柱子,然後把底盤移到第三個柱子,然後把第二個柱子的盤子移動到第三個
但基本的漢諾塔問題的操作是沒有限制的,就是你想移哪兒移哪兒,但是這題不一樣,這題強制了一個操作優先級,所以要用不同的方法去做。
f[x][i]: 第x號柱子移i個盤子到最優柱子的最優解 
p[x][i]:第x號柱子移i個盤子到p[x][i]號柱子是最優解
那麽就有兩種情況,第一種就是普通的漢諾塔移動 
f[a][i]=f[a][i-1]+1+f[b][i-1];
另外一種就是特殊的 
a上i-1個盤子移至b上,將a上的第i個盤子,移至c。由於i個盤子還沒疊到一起,所以接下來還要再次移動b上的i-1個
如果移到c的話就是經典算法
如果i-1個盤子移到a的話,那麽最終就是移到b柱子上
f[a][i]=f[a][i-1]+1+f[b][i-1]+1+f[a][i-1]; 
*/ #include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #define ll long long using namespace std; int p[4][31],x[10],y[10]; int n; char s[3]; ll f[4][31]; int main() { scanf("%d",&n); for(int i=1;i<=6;i++) { scanf("%s",s); x[i]=s[0]-A+1,y[i]=s[1]-A+1; } for(int i=6;i>=1;i--) p[x[i]][1]=y[i];//倒著來的原因是優先級高的會覆蓋優先級低的,被覆蓋的我們就不要了 for(int i=1;i<=3;i++) f[i][1]=1LL; for(int i=2;i<=n;i++) { for(int a=1;a<=3;a++) { int b=p[a][i-1],c=6-a-b;//c是什麽?一號二號三號加起來是6嘛,減去其他兩個不就是剩下那個了? if(p[b][i-1]==c) { f[a][i]=f[a][i-1]+1+f[b][i-1];//1是底盤移動的步數 p[a][i]=c; } else if(p[b][i-1]==a) { f[a][i]=f[a][i-1]+1+f[b][i-1]+1+f[a][i-1]; p[a][i]=b; } } } printf("%lld\n",f[1][n]); return 0; }

bzoj1019: [SHOI2008]漢諾塔(dp)