PTA Yet Another Hanoi Problem(递推)

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:
PTA Yet Another Hanoi Problem(递推)_第1张图片
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.

Input Specification:

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.

Output Specification:

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.

Sample Input:

3
1
2
3

Sample Output:

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;
}

你可能感兴趣的:(PTA)