寻找四塔函数g(x)的递推式。
我们将普通的3塔,即Hanoi塔问题的函数式记作f(x),易得f(x)=2^x-1。我们设一开始把x块东西中的a块放到第二个柱子上,这步用了g(a)次,然后,接下来x-a块放到第四个柱子上,由于只有3个柱子可以用,因此这步用了f(x-a)次。然后再把a块移过去用了g(a),所以总共消耗2*g(a)+f(x-a),所以g(x) = min{2*g(a)+f(x-a)},0<a<x,然后通过手工计算得:
注意到g(x)-g(x-1)的值为2个2,3个4,4个8……k个2^(k-1)
于是我们就可以通过一个O(n)的递推算法算出g(x)的值。而g(x)这样计算的正确性可以通过f(x)和g(x)的改变量来证明得到。
于是可以写出如下代码:
我们将普通的3塔,即Hanoi塔问题的函数式记作f(x),易得f(x)=2^x-1。我们设一开始把x块东西中的a块放到第二个柱子上,这步用了g(a)次,然后,接下来x-a块放到第四个柱子上,由于只有3个柱子可以用,因此这步用了f(x-a)次。然后再把a块移过去用了g(a),所以总共消耗2*g(a)+f(x-a),所以g(x) = min{2*g(a)+f(x-a)},0<a<x,然后通过手工计算得:
n | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
f(x) | 1 | 3 | 7 | 15 | 31 | 63 | 127 | 255 | 511 |
g(x) | 1 | 3 | 5 | 9 | 13 | 17 | 25 | 33 | 41 |
于是我们就可以通过一个O(n)的递推算法算出g(x)的值。而g(x)这样计算的正确性可以通过f(x)和g(x)的改变量来证明得到。
于是可以写出如下代码:
#include<iostream>
using namespace std;
const int R = 10000;
int FourHanoi(long n);
int main()
{
long n;
while(cin>>n)
cout<<FourHanoi(n)<<endl;
return 0;
}
int FourHanoi(long n)
{
long exp2 = 1, k = 1, result = 0;
while(n >= k)
{
result += (exp2 * k);
result %= R;
exp2 = (exp2 << 1) % R;
n -= k;
k++;
}
result += (exp2 * n);
return result % R;
}
using namespace std;
const int R = 10000;
int FourHanoi(long n);
int main()
{
long n;
while(cin>>n)
cout<<FourHanoi(n)<<endl;
return 0;
}
int FourHanoi(long n)
{
long exp2 = 1, k = 1, result = 0;
while(n >= k)
{
result += (exp2 * k);
result %= R;
exp2 = (exp2 << 1) % R;
n -= k;
k++;
}
result += (exp2 * n);
return result % R;
}