Strange Towers of Hanoi
Time Limit: 1000MS | Memory Limit: 30000K | |
Total Submissions: 2195 | Accepted: 1446 |
Description
Background Charlie Darkbrown sits in another one of those boring Computer Science lessons: At the moment the teacher just explains the standard Tower of Hanoi problem, which bores Charlie to death! The teacher points to the blackboard (Fig. 4) and says: "So here is the problem:
- There are three towers: A, B and C.
- There are n disks. The number n is constant while working the puzzle.
- All disks are different in size.
- The disks are initially stacked on tower A increasing in size from the top to the bottom.
- The goal of the puzzle is to transfer all of the disks from tower A to tower C.
- One disk at a time can be moved from the top of a tower either to an empty tower or to a tower with a larger disk on the top.
Input
There is no input.
Output
For each n (1 <= n <= 12) print a single line containing the minimum number of moves to solve the problem for four towers and n disks.
Sample Input
No input.
Sample Output
REFER TO OUTPUT.
Source
, Darmstadt, Germany
首先给出状态转移方程:dp[n]=min((dp[n-k] << 1) + (1 << k) - 1). 1<=k<=n
可能有的童鞋不熟悉“<<”运算,这里1<<k就是2^k,dp[n-k] << 1相当于dp[n-k] *2。
这里dp[n]表示盘子个数为n时问题的最优解,(1 << k) - 1就是三根柱子时要移动k个盘子的最小次数,关于此公式的推导见 。
要得出此状态转移方程只需根据题目中的以下描述:
At first k >= 1 disks on tower A are fixed and the remaining n-k disks are moved from tower A to tower B using the algorithm for four towers.Then the remaining k disks from tower A are moved to tower D using the algorithm for three towers. At last the n - k disks from tower B are moved to tower D again using the algorithm for four towers (and thereby not moving any of the k disks already on tower D). Do this for all k 2 ∈{1, .... , n} and find the k with the minimal number of moves.
也就是说,其实题目已经提供了算法。。。只需了解常规的汉诺塔问题并编程实现即可。
AC Code:
1 #include2 #include 3 4 using namespace std; 5 6 int main() 7 { 8 int dp[13] = { 0, 1, 3, 5}; 9 for(int n = 4; n < 13; n++)10 {11 dp[n] = 0xfffff;12 for(int k = 1; k <= n; k++)13 {14 int t = (dp[n-k] << 1) + (1 << k) - 1;15 if(dp[n] > t) dp[n] = t;16 } 17 }18 for(int i = 1; i < 13; i++) printf("%d\n", dp[i]);19 return 0;20 }