数论小知识(错排、斯特林)

来源:互联网 发布:linux 解压bz2命令 编辑:程序博客网 时间:2024/04/27 15:16

斯特林数:参考维基百科stirling数

第一类Stirling数是有正负的,其绝对值是n个元素的项目分作k个环排列的方法数目。

给定s(n,0) = 0,s(1,1) = 1,有递归关系S(n,k) =S(n − 1,k − 1) + (n-1)S(n − 1,k)

第二类Stirling数n个元素的集定义k个等价类的方法数目。

给定S(n,n) =S(n,1) = 1,有递归关系S(n,k) =S(n − 1,k − 1) +kS(n − 1,k)

第一类stirling数的样题:hdu3625

公式的推导过程:

n个数分成0组有0中排列,一个数分成一组有一种排列。

n个数分成k组,是(一个新数自己一组其余n-1个数分成k-1组  )和 (在n-1个分成k组中插入新数,有n-1种插入方式)

代码:

#include <iostream>#include <stdio.h>using namespace std;long long num[22][22];long long  fun(int n)//求阶乘{long long ss=1;while(n>0) {ss*=n;n--;}return ss;}int  main(){int t,i,j;cin>>t;memset(num,0,sizeof(num));//stirling公式num[1][1]=1;for (i=2;i<21;i++){for (j=1;j<=i;j++){num[i][j]=num[i-1][j-1]+(i-1)*num[i-1][j];}}while (t--){int n,k;cin>>n>>k;long long rr=0;for (i=1;i<=k;i++){rr+=num[n][i]-num[n-1][i-1];//减去1自己成环的排列}double re=(double)rr/fun(n);printf("%.4lf\n",re);}return 0;}


斯特林公式

求n的阶乘的近似值:

n!=sqrt(2*PI*n)*(PI/e)^n;

位数:len=(int)ceil((N*log(N)-N+log(2*N*PI)/2)/log(10));   //////ceil求上界,即不小于某值的最小整数

错排公式

n各有序的元素应有n!种不同的排列。如若一个排列式的所有的元素都不在原来的位置上,则称这个排列为错排。任给一个n,求出1,2,……,n的错排个数dn共有多少个。

递归关系式为:d(n)=(n-1)(d(n-1)+d(n-2))

d(1)=0,d(2)=1

可以得到:

错排公式为dn=n!(1-1/2!+1/3!-.....+(-1)n/n!)   其中,n!=1*2*3*.....*n,   特别地,有0!=0,1!=1.

斐波那契数列的近似值:

Fn=(1/√5) * [((1+√5)/2)^n-((1-√5)/2)^n](n=1,2,3.....)

两边同时取对数得到:
log10(Fn)=-0.5*log10(5.0)+((double)n)*log(f)/log(10.0)+log10(1-((1-√5)/(1+√5))^n)

其中f=(sqrt(5.0)+1.0)/2.0;
因为log10(1-((1-√5)/(1+√5))^n)趋近于0
所以log10(Fn)=-0.5*log10(5.0)+((double)n)*log(f)/log(10.0);

样题:hdu1568 代码:

#include<iostream>#include<cmath>#include<cstdio> using namespace std;const double f = (sqrt(5.0)+1.0)/2;int main(){    int n,i;    double bit;    int fac[21] = { 0 , 1 };    for(i = 2; i < 21; i++)         fac[i] = fac[i-1] + fac [i-2];    while(cin >> n)    {        if(n <= 20) {            cout << fac[n] << endl;            continue;        }        else{            bit = -0.5*log(5.0)/log(10.0)+((double)n)*log(f)/log(10.0);            bit = bit - floor(bit);             bit = pow(10.0,bit);             while(bit < 1000)                 bit = 10.0 * bit;             cout << (int)bit << endl;            }    }    return 0;}


原创粉丝点击