回复 19楼 bbb222
你让我给你解释C语言?
static __int64 ComputeA( unsigned int N );
static __int64 ComputeC( unsigned int n, unsigned int m );
// 求n取m的组合
// n取m的组合计算公式为:
// [n * ( n - 1 ) * ... * ( n - m + 1 )]/[m*(m-1)*...*1]
static __int64 ComputeC( unsigned int n, unsigned int m )
{
__int64 iResult = 0;
__int64 iDev;
if ( m <= n )
{
if ( m > ( n / 2 ) )
{
// 对于c(n,m)当m> n/2时c(n,m)=c(n,n-m)
// 因此为了简化计算,将m变成小于n/2的值
m = n - m;
}
iResult = 1;
for( unsigned int i = 0; i < m; i++ )
{
iResult *= ( n - i ); // 计算n*(n-1)*...*(n-m+1)
iDev = i + 1; // 同时除以1*2*..*m
// 可以用数学方法证明先乘的乘数,同时除以小的除数
// 可保证永远够除
iResult /= iDev;
}
}
return iResult;
}
// 计算bits个比特为不含任意连续1的所有可能取值
// 若N为偶数,则满足要求的数量是G=C(N,1)+C(N-1,2)+...+C(K+1,N-K+1) + 1,其中K=N/2
// 若N为奇数,则满足要求的数量是G=C(N,1)+C(N-1,2)+...+C(K, N-K+1) + 1,其中K=(N+1)/2
static __int64 ComputeA( unsigned int N )
{
__int64 iResult = 0;
unsigned int k = ( N + 1 ) / 2;
if ( !( N & 1 ) )
{
// 对于偶数,从k+1开始计算
k++;
}
for( unsigned int i = k; i <= N; i++ )
{
// 计算c( k, n-K+1)+...+c(N,1)
// 当i=k时计算c(k, N-K+1)
// 当i=N时计算c(N,1)
iResult += ComputeC( i, N - i + 1 );
}
return iResult + 1;
}
另:
可以证明
c(n,k)+c(n,k+1)=c(n+1,k+1)
于是
当n为偶数时
f(n) = c(n, 0)+c(n, 1)+c(n-1,2)+...+c(k+1,k)
f(n+1) =c(n+1,0)+c(n+1,1)+c(n, 2)+c(n-1,2)+...+c(k+1,k+1)
f(n+2) =c(n+2,0)+c(n+2,1)+c(n+1,2)+c(n, 3)+...+c(k+2,k+1)
因c(n+1,0)=c(n+2,0)
c(n,0)+c(n+1,1)=c(n+2,1)
因此f(n+2)=f(n+1)+f(n)
当n为奇数时
f(n) = c(n, 0) +c(n, 1)+c(n-1,2)+...+c(k+1,k-1)+c(k,k)
f(n+1) =c(n+1,0)+c(n+1,1) +c(n, 2)+c(n-1,2)+...+c(k+1,k)
f(n+2) =c(n+2,0)+c(n+2,1) +c(n+1,2)+c(n, 3)+...+c(k+2, k)+c(k+1,k+1)
其中c(n+1,0)+c(n+1,1)=c(n+2,1)
c(n+2,0)=c(n,0)
c(k,k)=(k+1,k+1)
其它每组c(n,1)+c(n,2)=c(n+1,2)
也满足f(n+2)=f(n+1)+f(n)
根据上面,无论n为奇数或偶数都可以证明
f(n+2)=f(n+1)+f(n)
原来真的是兔子数啊。。。