关于傻子坐飞机问题的答案 (算法的改进)

 

/*  本程序是求下面关于傻子坐飞机的问题:
 * 100个人排队乘坐有100个座位的飞机,正常情况时每个都都会对号入坐,但是,
 * 第一个上飞机的是个傻子,他随机坐了一个位子,接下来的人上飞机时,如果
 * 自己座位被人坐了就会随机找个座位坐下,否则就坐自己坐位。问题:最后一
 * 个上飞机的人坐到自己座位的概率是多少?? 
*/

using  System;

namespace  Stupid
{
    
class  Program
    {
        
///   <summary>
        
///  用来保存已经计算过的结果
        
///   </summary>
         private   double [] result;

        
public  Program()
        {
            result 
=   new   double [ 100 ];
        }

        
///   <summary>
        
///  求最后一个上飞机的人坐到自己座位的概率
        
///   </summary>
        
///   <param name="n"></param>
        
///   <returns></returns>
         public   double  F( int  n)
        {
            
double  s  =   0 ;
            
double  f = 0 ;
            
if  (n  ==   2 )
            {
                
return   0.5 ;
            }
            
else
            {
                
for  ( int  i  =   2 ; i  <  n; i ++ )
                {
                    
if  (result[i  -   1 !=   0 )
                        s 
+=  result[i  -   1 ];
                    
else
                    {
                        f 
=  F(i);
                        s 
+=  f;
                        result[i 
-   1 =  f;
                    }
                }
                
return  (s + 1 ) / ( double )(n);
            }
        }

        
///   <summary>
        
///  程序入口
        
///   </summary>
        
///   <param name="args"></param>
         static   void  Main( string [] args)
        {
            
double  starttime, spendtime;
            starttime 
=  System.DateTime.Now.Ticks;
            Console.WriteLine(
" Result={0} " new  Program().F( 100 ));
            
// 计算所需时间
            spendtime  =  (System.DateTime.Now.Ticks  -  starttime)  /   1000000.0 ;
            Console.WriteLine(
" 计算所需时间:{0:f3} " , spendtime);
            Console.Read();
        }
    }   
}

 

 采用以上算法(只是对我原来算法的一个改进,当然如果能够改成非递归算法那就更好)

当n=100时,只需0.1秒左右的时间就可以算出来.

以下是我对这个问题的非递归算法解答:

 


        
///   <summary>
        
///  求最后一个上飞机的人坐到自己座位的概率
        
///  非递归算法
        
///   </summary>
        
///   <param name="n"></param>
        
///   <returns></returns>
         public   double  F2( int  n)
        {
            
double [] result  =   new   double [n  +   1 ];
            result[
1 =   1 ;
            
for  ( int  i  =   2 ; i  <=  n; i ++ )
            {
                
for  ( int  j  =   1 ; j  <  i; j ++ )
                    result[i] 
+=  result[j];
                result[i] 
/=  ( double )i;
            }
            
return  (n  >   0   ?  result[n] :  0 );
        }

 

我对两种算法通过重复几十次的运算,结果所花费的时间是一致的,有点出乎我的预料.

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值