Description
求组合数C(n,m)
Input
T(0 < T < 2000)每组样例两个数n, m(0 < n, m< 60)
Output
C(n,m)
Sample Input
2
1 1
2 1
Sample Output
1
2
思路:题目似不似超级简单?!but, C(60,30) = 118264581564861424,,,如果按原来的做法就是直接用组合数公式C(n, m) = n!/(m!* (n-m)!),之后就会发现,即使是long long 也存不下最大的60!,,,所以,,,
你应该在边乘的同时边除以,这样就保证了不会溢出,(而为什么会刚好约掉呢?自己想吧!)
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<map>
#include<vector>
#include<stdlib.h>
#include<cstring>
#include<string.h>
#include<math.h>
using namespace std ;
typedef long long ll;
#define maxn 10000005
#define INF 0x3f3f3f3f//将近int类型最大数的一半,而且乘2不会爆int
int main()
{
int n;
scanf("%d", &n);
for(int i=0; i<n; ++i)
{
ll a, b;
scanf("%lld %lld", &a, &b);
ll ans=1, tem=1;
for(ll j=1; j<=b; j++)//组合数的另一公式
{
tem *= (a-j+1);//乘分子,除方面,保证不溢出
tem /= j;
}
printf("%lld\n", tem);
}
return 0;
}
这个,,好像是用乘法逆元也可以A。。。。。