c++ 详讲求组合数

C++中组合数可以使用递归或迭代的方式计算。组合数的概念是指从n个不同元素中取出m个元素的方案数,可以表示为C(n,m),也可以表示为n choose m。组合数有以下性质:

  1. C(n,m) = C(n,n-m)
  2. C(n,0) = 1
  3. C(n,n) = 1
  4. C(n,m) = C(n-1,m-1) + C(n-1,m)

这些性质可以用来简化计算组合数的过程。

在实际应用中,组合数有许多用处。例如:

  1. 排列组合问题:计算从n个元素中取出m个元素进行排列的方案数。
  2. 概率论中的组合数:计算从n个元素中任选m个元素的组合中,满足某些条件的方案数。
  3. 离散数学中的组合数:计算符合某种性质的字符串或序列的方案数。
  4. 组合优化问题:计算在某些限制条件下,从n个元素中取出m个元素的方案数,以及求解某些最优解问题。

在编程中,可以使用递归或迭代的方式实现计算组合数。以下为使用递归方式计算组合数的示例代码

long long C(int n, int m) {
    if (m == 0 || m == n) {
        return 1;
    }
    return C(n - 1, m - 1) + C(n - 1, m);
}
 

使用迭代方式计算组合数的示例代码如下:

long long C(int n, int m) {
    long long res = 1;
    m = min(m, n - m);
    for (int i = 0; i < m; ++i) {
        res *= (n - i);
        res /= (i + 1);
    }
    return res;
}
 

这种方式比递归方式更高效,因为递归方式存在大量的重复计算,而迭代方式可以通过记录中间结果来避免重复计算。

题目一:

给定 n 组询问,每组询问给定两个整数 a,b,请你输出 Cbamod(109+7) 的值。

输入格式

第一行包含整数 n。

接下来 n 行,每行包含一组 a 和 b。

输出格式

共 n 行,每行输出一个询问的解。

数据范围

1≤n≤10000
1≤b≤a≤2000

输入样例

3
3 1
5 3
2 2

输出样例

3
10
1

具体代码

#include
#include

using namespace std;

const int N=2010,mod=1e9+7;

int c[N][N];

void init()
{
    for(int i=0;i>n;
    
    init();
    
    while(n--)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        
        printf("%d\n",c[a][b]);
    }
    return 0;
}

思路:第一层循环从底数开始,所以从N开始,第二层循环从i开始,减少时间复杂度,下面那就是一个数学公式

问题二:

给定 n 组询问,每组询问给定两个整数 a,b,请你输出 Cbamod(109+7)的值。

输入格式

第一行包含整数 n。

接下来 n 行,每行包含一组 a 和 b。

输出格式

共 n 行,每行输出一个询问的解。

数据范围

1≤n≤10000
1≤b≤a≤10^5

具体代码

#include
#include

using namespace std;

typedef long long LL;

const int N=100010,mod=1e9+7;

int fact[N],infact[N];

int qmi(int a,int b,int p)
{
    int res=1;
    while(b)
    {
        if(b&1) res=(LL)res*a%p;
        a=(LL)a*a%p;
        b>>=1;
    }
    return res;
}

int main()
{
    int n;
    cin>>n;
    
    fact[0]=infact[0]=1;
    for(int i=1;i

1、用费马小定理求逆元

2、快速幂

你可能感兴趣的:(c++,算法)