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