poj-2249

// 356K 16MS    G++
// 356K 0MS G++ add m ==0 check
// 356K 16MS    G++
// 356K 0MS G++ add m ==0 check
#include <stdio.h>
#include <string.h>
#include <math.h>


int m;
int n;


// void getNum(unsigned int n, unsigned int m) {  
//     // long long total = n;  
//     m = m < (n -m) ? m : (n -m);
//     if (m == 0) {
//         printf("1\n");
//         return;
//     }
//     long long cnm = 1;  
//     for (long i = 1; i <=m ; i++) {
//         cnm = cnm*(n-i+1)/i;
//     }


//     printf("%lld\n", cnm);  
// }  
  
void getNum(unsigned int n, unsigned int m) {  
    if (m == 0 || m == n) {
        printf("1\n");
        return;
    }
    m = m < (n -m) ? m : (n -m);  
    
    double cnm = 1.0;  
    while(m>0)  
        cnm *= (double)(n--)/(double)(m--);  
    cnm+=0.5;  
    printf("%lld\n", (long long)cnm);  
}  


int main() {  
    while(scanf("%d %d", &n, &m) != EOF) {  
        if (!m && !n) {  
            return 0;  
        } else if (!n) {  
            printf("0\n");  
        } else if (!m) {
            printf("1\n");  
        } else{  
            getNum(n, m);  
        }  
    }  
} 

要说算是道水题, 重点考察:

C(n,m) = C(n,m-1) * (n-m+1) / m.

C(n,m) = C(n,n-m).

尤其是第二个公式, 如果不做这个检测(取m 和 n-m中最小的 来求组合数),铁定TLE,题目的测试数据也应该都是这种类型的, n-m 或 m中会有一个很小的数,使得运算量不会很大(题目很贴心的说了结果  it will be less than 2 31) , 一开始还以为是道超级水题,直接把二维数组递推求组合搞上去,结果果真RE,然后使用之前用过的组合优化求法, 以及 上面的公式(分别对应code里两个getNum()), 都得到了0ms的结果
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值