斯特林数:参考维基百科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; }