poj 1942 组合数问题

这篇博客讨论了如何高效地处理组合数问题,特别是针对POJ 1942这道题目。博主指出使用double存储中间结果是一种巧妙的方法,并且比较了三种不同的阶乘计算策略:直接递归、利用对数化乘为加以及拆分阶乘逐项相除。最后推荐使用拆分阶乘的方法,因为它的时间复杂度更低且避免了精度损失问题。
摘要由CSDN通过智能技术生成

本题很简单,但处理方法也很特殊,用double来存中间结果,神!

同样的公式,不同的处理方法,效果不同。 如:选择n时一定选小的,节约时间。

 

处理阶乘有三种办法:

(1)       传统意义上的直接递归,n的规模最多到20+,太小了,在本题不适用,而且非常慢

(2)       稍快一点的算法,就是利用log()化乘为加,n的规模虽然扩展到1000+,但是由于要用三重循环,一旦n规模变得更大,耗时就会非常之严重,时间复杂度达到O(n*m*(n-m)),本题规定了n,m用unsigned int32类型,就是说n,m的规模达到了21E以上,铁定TLE的。而且就算抛开时间不算,还存在一个致命的问题,就是精度损失随着n的增加会变得非常严重。

因为n有多大,就要进行n次对数运算,n规模一旦过大,就会丢失得非常严重了。所以这种方法是绝对不可取的,因为中途的精度丢失不是简单的四舍五入可以挽回的。

(3)       拆分阶乘,逐项相除,再乘以前面所有项之积。这种方法用一个循环就OK了,时间复杂度只有O(n-m),非常可观。

 

 

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath&
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值