关于Cm取n
我们知道,用公式m!/(n!*(m-n)!)可以得到结果,用计算机计算可以用乘法递归得到结果,但若m较大时则无论怎样都会产生溢出。我写了一个程序可以得到m较大时的结果,结果用双长整形保留,也就是说结果仍然有限。
这种方法的基本思想是采用杨辉三角的规律来做。杨辉三角与组合密切相关,它每一行的每一个数代表了(a + b)的n次方的系数,即Cm取n的结果。按照这个规律,用一个长度为m+1的数组保留杨辉三角的每一行的结果,先置0号元素为1,其余元素为0,从m+1行,m+1列开始从后往前加,即array[i] = array[i - 1] + arrar[i],这样就能得到第m行的杨辉三角数,然后直接取第n号元素即为结果,下面是代码:
#include <iostream>
using namespace std;
/*用双长整形保存扬辉三角数,将在第67行溢出*/
int get_yanghui(long long int* arr, int m)
{
int i = 1, j = 0;
long long temp = 0;
for(j = 1; j < m + 1; j++)
for(i = j; i > 0; i --)
{
temp = *(arr + i - 1) + *(arr + i);
if(temp < 0)
return -1;
*(arr + i) = temp;
}
return 0;
}
long long solve(long long int *arr, int m, int n)
{
*arr = 1;
if(get_yanghui(arr, m) == 0)
return *(arr + n);
else
return -1;
}
int main()
{
long long resu = 1;
int m = 0, n = 0;
cin >> m >> n;
long long int* arr = new long long int[m + 1];
memset(arr, 0, sizeof(long long int) * (m + 1));
cout << solve(arr, m, n) << endl;
system("pause");
return 0;
}