SDNUOJ—— 1245 这题超难的(不, 这题不难!)

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。。。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值