poj1423

偏数学题:主要用到Stirling公式 
 

1。用Stirling公式

公式和证明如下:

An important formula in applied mathematics as well as in probability is the Stirling's formula known as 

 


 

where  is used to indicate that the ratio of the two sides goes to 1 as n goes to . In other words, we have 

 

/begin{displaymath}/lim_{n /rightarrow /infty} /frac{n!}{/sqrt{2 /pi} /; n^{/displaystyle (n+ 1/2)}e^{/displaystyle-n}} = 1/end{displaymath}


 

or 

 

/begin{displaymath}/lim_{n /rightarrow /infty} /frac{n!}{ n^{/displaystyle (n+ 1/2)}e^{/displaystyle-n}} = /sqrt{2 /pi}/;./end{displaymath}


 

 

Proof of the Stirling's Formula

First take the log of n! to get 

 

/begin{displaymath}/log(n!) = /log (1) + /log(2) + /cdots + /log(n)/;./end{displaymath}


 

Since the log function is increasing on the interval , we get 

 

/begin{displaymath}/int_{n-1}^{n} /log(x) dx < /log(n) < /int_{n}^{n+1} /log(x) dx/end{displaymath}


 

for . Add the above inequalities, with $n=1,2,/cdots,N$, we get 

 

/begin{displaymath}/int_{0}^{N} /log(x) dx < /log(N!) < /int_{1}^{N+1} /log(x) dx/end{displaymath}


 

Though the first integral is improper, it is easy to show that in fact it is convergent. Using the antiderivative of  (being $x /log(x) -x$), we get 

 

/begin{displaymath}n/log(n) - n < /log(n!) < (n+1)/log(n+1) - n/;./end{displaymath}


 

Next, set 

 


 

We have 

 


 

Easy algebraic manipulation gives 

 

/begin{displaymath}/frac{n+1}{n} = /frac{1 + /displaystyle /frac{1}{2n+1}}{1 - /displaystyle /frac{1}{2n+1}}/;./end{displaymath}


 

Using the Taylor expansion 

 


 

for -1 < t < 1, we get 

 

/begin{displaymath}d_n - d_{n+1} = /frac{1}{3} /frac{1}{(2n+1)^2} + /frac{1}{5} /frac{1}{(2n+1)^4} + /cdots/end{displaymath}


 

This implies 

 


 

We recognize a geometric series. Therefore we have 

 


 

From this we get

1.
the sequence  $/{d_n/}$ is decreasing;
2.
the sequence  $/left/{d_n - /displaystyle /frac{1}{12n}/right/}$ is increasing.

This will imply that $/{d_n/}$ converges to a number C with 

 

/begin{displaymath}/lim_{n /rightarrow /infty} d_n = /lim_{n /rightarrow /infty} d_n - /displaystyle /frac{1}{12n} = C /end{displaymath}


 

and that C > d1 - 1/12 = 1 - 1/12 = 11/12. Taking the exponential of dn, we get 

 


 

The final step in the proof if to show that $e^C = /sqrt{2/pi}$. This will be done via Wallis formula (and Wallis integrals). Indeed, recall the limit 

 

/begin{displaymath}/lim_{n /rightarrow /infty} /frac{2.2.4.4.6.6/ldots(2n)(2n)}{1.1.3.3.5.5./ldots(2n-1)(2n-1)(2n+1)}/;= /frac{/pi}{2}/;./end{displaymath}


 

Rewriting this formula, we get 

 

/begin{displaymath}/frac{2.4.6/ldots(2n)}{1.3.5./ldots(2n-1) /sqrt{2n}} /sim /sqrt{/frac{/pi}{2}}/end{displaymath}


 

Playing with the numbers, we get 

 


 

Using the above formula 

 

/begin{displaymath}n! /sim n^{/displaystyle (n+ 1/2)}e^{/displaystyle-n} e^{C}/;./end{displaymath}


 

we get 

 

/begin{displaymath}/frac{2^{2n} /Big(n^{2n+1} e^{-2n} e^{2C}/Big)}{(2n)^{(2n+1/2)} e^{-2n} e^C}/frac{1}{/sqrt{2n}} /sim /sqrt{/frac{/pi}{2}}/end{displaymath}


 

Easy algebra gives 

 

/begin{displaymath}e^C /sim /sqrt{2/pi}/end{displaymath}


 

since we are dealing with constants, we get in fact $e^C = /sqrt{2/pi}$. This completes the proof of the Stirling's formula.

AC code:

# include <stdio.h> # include <math.h> int n; const   double  e  =   2.7182818284590452354 ,   pi   =   3.141592653589793239 ; double  f( int a ){     return   log10 sqrt 2   *   pi   *  a ) )  +  a  *   log10 ( a  /  e );}int main(){    int cas ,  ans;     double  i ,  s;        scanf(  " %d " ,   & cas );         while ( cas --  )    {        scanf(  " %d " ,   & n );         if ( n  <   100000  )        {             for ( s = 0 ,  i = 1 ; i <= n; i ++  )                s  +=   log10 ( i );        }         else  s  =  f( n );        ans  =  (int)s;         if ( ans  <=  s )            ans ++ ;                 printf " %d/n " ,  ans );    }         return   0 ;}

 

2。用 位数=[ lg1+lg2+……lg(N-1)+lgN ] + 1。

数很大时,速度会慢,TLE。。

所以如上述AC代码,小于100000时,可以用这种方法,再大的话最好用Stiring公式。

运用Stirling公式写的AC了的C代码:

#include<stdio.h>
#include<math.h>

const double E = 2.7182818284590452354, PI = 3.141592653589793239;

int main()
{
	int n,i;
	int value;
	double stirlingValue;
	int result;
	scanf("%d",&n);
	for(i=0;i<n;i++){
		scanf("%d",&value);
		
		if(value==0||value==1){
			result=1;
		}else{
			stirlingValue=log10(value/E)*value+log10(sqrt(2*PI*value));
			
			result=(int)stirlingValue;
			result+=result<stirlingValue?1:0;
		}
		
		printf("%d\n",result);
	}
	return 0;
}


你可能感兴趣的:(poj1423)