/*
问题描述:
100 个台阶, 每次可以走 1 或 2 或 3 个台阶, 走完这 100 个台阶共有多少种走法?
基本思想:
f(1) = 1;
f(2) = 2;
f(3) = 4;
f(n) = f( n-1 ) 最后一步为 1
+ f( n-2 ) 最后一步为 2
+ f( n-3 ) 最后一步为 3
*/
double recursion1( int n )
{
if( n == 1 )
return 1;
else if( n == 2 )
return 2;
else if( n == 3 )
return 4;
else
{
printf("%5d", n );
return recursion1( n-1 ) + recursion1( n-2 ) + recursion1( n-3 );
}
}
double recursion2( int n )
{
/*
算法思想:
将已经算出的 数保存在 cash[] 中, 每次先在 cash[] 中查找, 如果找到则不再递归, 直接返回结果.
*/
static double cash[100] = {0,1,2,4};
if( cash[n] != 0 )
return cash[n];
else
{
printf("%5d", n );
cash[n] = recursion2( n - 3 ) + recursion2( n-2 ) + recursion2( n-1 );
return cash[n];
}
}
double no_recursion1( int n )
{
if( n == 1 )
return 1;
else if( n == 2 )
return 2;
else if( n == 3 )
return 4;
double t_3 = 1; // record f( n-3 )
double t_2 = 2; // record f( n-2 )
double t_1 = 4; // record f( n-1 )
double sum = 0;
for( int i = 4; i <= n; i ++ )
{
// f(n) = f( n-1 ) + f( n-2 ) + f( n-3 )
sum = t_1 + t_2 + t_3;
// update f( n-1 ), f( n-2 ), f( n-3 )
t_3 = t_2;
t_2 = t_1;
t_1 = sum;
}
return sum;
}
double ff( int end, int beg = 1 )
{
if( end == 0 || end == 1)
return 1;
double ss = 1;
for( int i = beg; i <= end ; i ++ )
ss *= i;
return ss;
}
double no_recursion2( int nn )
{
/*
算法思想:
找出满足 x + 2y + 3z == nn 的所有 x, y, z, 之后问题变成一个重集 B 上的全排列问题:
其中 B = { x.1, y.2, z.3 },
公式为: nn!/( x! * y! * z! )
(此处对阶乘算法没有进一步优化)
*/
double sum = 0;
for( int z = 0; z < 34; z ++ )
{
for( int y = 0; y < 51; y ++ )
{
for( int x = 0; x < 101; x ++ )
{
if( x + 2*y + 3*z != nn )
continue;
// x + 2y + 3z == 100
double t1 = ff( x );
double t2 = ff( y );
double t3 = ff( z );
double t4 = ff( x + y + z );
double tem = t4 / ( t1 * t2 * t3 );
sum += tem;
printf("%5d%5d%5d%50.0f/n", x, y, z, tem );
}
}
}
return sum;
}
int main()
{
//double sum = recursion1( 25 ); // 25 is the MAX number that I can bear!
double sum = recursion2( 100 );
//double sum = no_recursion1( 100 );
//double sum = no_recursion2( 100 );
printf("/n/nsum is: %.0f", sum );
printf("/n/nsum is: %.20G/n", sum );
}