杨辉三角求组合数

#include <vector>

namespace XDC{
	typedef long long ll;


	const int MOD = 1e9 + 7;

	const int dirX[] = {1,-1,0,0};
	const int dirY[] = {0,0,1,-1};

	//杨辉三角求组合数
	class YangHuiTriangle{
	private:
		std::vector< std::vector<ll> > angle;
		int m_len;
	public:
		YangHuiTriangle(int len);
		bool Init(int len);
		ll  C(int m, int n);
	};

	//求阶乘
	extern ll GetFactorial(int n);

	//求排列数
	//n!/(n-m)!
	extern ll P(int m, int n);

	//求组合数
	extern ll C(int m, int n);
	
	//求次方
	extern  double Pow(double x, int n);
};

//using namespace XDC;

实现

#include "Xdc.h"
#include <algorithm>

namespace XDC{

	YangHuiTriangle::YangHuiTriangle(int len)
	{
		Init(len);
	}

	bool YangHuiTriangle::Init(int len)
	{
		if (len <= 0) return false;

		angle.clear();

		m_len = len;

		angle.assign(len, std::vector<ll>(len, 1));

		for (int i = 2; i < len; ++i){
			for (int j = 1; j < i; ++j){
				angle[i][j] = angle[i-1][j-1] + angle[i-1][j];
			}
		}

		return true;
	}

	ll YangHuiTriangle::C(int m, int n)
	{
		if (m < 0 || n < 0 || n >= m_len || m >= m_len) return -1;

		if (m > n) return C(n, m);

		if (m == 0 || m == n) return 1;

		return angle[n][m];
	}

	//求阶乘
	ll GetFactorial(int n){
		if (n < 0) return -1;
		if (n <= 1) return 1;

		ll ret = 1;
		for (ll i = 2; i <= n; ++i){
			ret = ret * i;
		}
		return ret;
	}

	//求排列数
	//n!/(n-m)!
	ll P(int m, int n)
	{
		if (m < 0 || n < 0) return -1;
		if (m > n) return P(n, m);

		ll ret = 1;
		for (ll i = n; i > n - m; --i){
			ret = ret * i;
		}
		return ret;
	}

	//求组合数
	//n!/  ((n-m)! * m!) 朴素的解法
	ll _C(int m, int n){
		if (m < 0 || n < 0) return -1;
		if (m > n) return _C(n, m);

		if (m > n / 2) return _C(n - m, n);

		if (m == 0 || n == m) return 1;

		ll _m = 1,_n = 1;
		for (int i = 2; i <= m; ++i){
			_m = _m * i;
		}
		for (int i = n; i>n - m; i--){
			_n = _n * i;
		}
		return _n / _m;
	}

	//杨辉三角
	ll _C_YangHui(int m, int n){

		YangHuiTriangle angle(std::max(n,m));

		return angle.C(m, n);
	}
	ll C(int m, int n){

		if (std::max(m, n) <= 10) return _C(m, n);

		return _C_YangHui(m, n);
	}
	
	double Pow(double x, int n)
	{
		if (n == 0) return 1;
		double ret = 1.0,base = x;

		while (n){
			if (n & 1){
				ret *= base;
			}
			base *= base;
			n = n >> 1;
		}
		return ret;
	}
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值