One day, Little Gyro saw Onlystar playing the Hanoi Tower and wanted to test him.
The ordinary Hanoi Tower is a game with three pillars A, B and C. Given a tower consisting of n discs, these discs are nested on the pillar A within a decreasing way of size to display. Our goal is to move the entire tower to another pillar C. Only one disc can be moved at a time, and the larger disc cannot be placed under the smaller disc during every movement. Here shows the picture of it:
Then Little Gyro modified the rule of the Hanoi Tower game, supposed that the relative position of three pillars A, B and C is from left to right. Onlystar was asked to move the entire tower consisting of n discs from the leftmost pillar A to the rightmost pillar C, However, he couldn’t move any disc directly from pillar A to pillar C. It means that Onlystar can only move discs through the pillar B in the middle.
Now, given the total number of discs, Onlystar wants to know the minimum steps there may be.
There are multiple test cases. The first line of the input contains an integer T (1 ≤ T ≤ 10
5
), indicating the number of test cases. For each test case:
Each line contains one integer n (1 ≤ n ≤ 10
6
), indicating the total number of discs.
For each test case, you should output the number of the minimum steps that Onlystar could achieve.
Because the number may be very large, just output the number mod 10
9
+7.
3
1
2
3
2
8
26
汉诺塔问题,明显是个递推问题
定义三个数组
dp[n] 表示将n个盘子从一个边缘移到另一个边缘位置的最小移动步数(也就是题目要求的次数)
f1[n] 表示将n个盘子从边缘移到中央位置的最小移动次数
f2[n] 表示将n个盘子从中央移到边缘位置的最小移动次数
于是可以有以下三个递推式
dp[i] = (f1[i - 1] + f2[i - 1]) * 3 + 2;
f1[i] = 2 * f1[i - 1] + f2[i - 1] + 1;
f2[i] = 2 * f2[i - 1] + f1[i - 1] + 1;
整理后有以下递推式
dp[i] = 3 * dp[i - 1] + 2
代码:
#include //7-2 Yet Another Hanoi Problem
#include
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 2;
const int P = 1e9 + 7;
ll dp[maxn];
ll f1[maxn];
ll f2[maxn];
// dp[i] = (f1[i - 1] + f2[i - 1]) * 3 + 2;
// f1[i] = 2 * f1[i - 1] + f2[i - 1] + 1;
// f2[i] = 2 * f2[i - 1] + f1[i - 1] + 1;
int main()
{
for (int i = 1; i < maxn; i++)
{
// dp[i] = ((f1[i - 1] + f2[i - 1]) % P * 3LL % P + 2LL) % P;
// f1[i] = (2LL * f1[i - 1] % P + f2[i - 1] + 1LL) % P;
// f2[i] = (2LL * f2[i - 1] % P + f1[i - 1] + 1LL) % P;
dp[i] = (3LL * dp[i - 1] % P + 2) % P;
//dp[i] = (((dp[i - 1] << 1) % P + dp[i - 1]) % P + 2) % P;
}
int T, k;
cin >> T;
while (T--)
{
cin >> k;
cout << dp[k] << endl;
}
system("pause");
return 0;
}