"100 个台阶"问题的 4 种解法

来源:互联网 发布:网络电视还需要盒子吗 编辑:程序博客网 时间:2024/04/26 00:13
 
/*
问题描述:
 
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 );
 
}
 
原创粉丝点击