首页 > 其他分享 >求组合数

求组合数

时间:2023-05-04 16:47:58浏览次数:33  
标签:组合 int res long using include

1.公式法

根据组合数递推公式求解

题目描述:

代码实现:

#include<iostream>
using namespace std;
const int N=2005,p=1e9+7;
long long dp[N][N];
void init(){
    for(int i=0;i<=2000;i++){
        for(int j=0;j<=i;j++){
            if(j==0)dp[i][j]=1;
            else dp[i][j]=(dp[i-1][j]+dp[i-1][j-1])%p;
        }
    }
}
int main(){
    int n;
    cin>>n;
    init();
    while(n--){
        int a,b;
        cin>>a>>b;
        cout<<dp[a][b]<<endl;
    }
    return 0;
}

2.快速幂加逆元

题目描述:

代码实现:

#include<iostream>
using namespace std;
#define int long long
const int N=1e5+5,p=1e9+7;
int f[N],inf[N];
int quick(int a,int b){
    int res=1;
    while(b){
        if(b&1)res=res*a%p;
        a=a*a%p;
        b>>=1;
    }
    return res;
}
signed main(){
    int n;
    cin>>n;
    f[0]=inf[0]=1;
    for(int i=1;i<=N;i++){
        f[i]=f[i-1]*i%p;//求i的阶乘
        inf[i]=inf[i-1]*quick(i,p-2)%p;//利用费马小定理求i的阶乘的逆元
    }
    while(n--){
        int a,b;
        scanf("%lld%lld",&a,&b);
        cout<<f[a]*inf[a-b]%p*inf[b]%p<<endl;//套公式求组合数
    }
    return 0;
}

3.卢卡斯定理

根据lucas定理求解组合数

其中组合数的直接求解方法是利用方法二的快速幂加逆元

代码实现:

#include<iostream>
using namespace std;
#define int long long
int p;
//用来求除法逆元
int quick(int a,int b,int p){
    int res=1;
    while(b){
        if(b&1)res=res*a%p;
        a=a*a%p;
        b>>=1;
    }
    return res;
}
int C(int a,int b,int p){
    int res=1;
    //直接利用原始公式求解组合数
    for(int i=a,j=1;j<=b;j++,i--){
        res=res*i%p;
        res=res*quick(j,p-2,p)%p;
    }
    return res;
}
int lucas(int a,int b,int p){
    if(a<p&&b<p)return C(a,b,p);//如果a和b都同时小于p,则可以直接求解组合数
    return C(a%p,b%p,p)*lucas(a/p,b/p,p)%p;//否则递归套公式降低系数求解组合数
}
signed main(){
    int n;
    cin>>n;
    while(n--){
        int a,b;
        cin>>a>>b>>p;
        cout<<lucas(a,b,p)<<endl;//直接套公式
    }
    return 0;
}

4.不带模数的组合计数

先对组合数进行分解质因数,再利用高精度乘法求解组合数

其中分解质因数利用线性筛

代码实现:

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
const int N=5005;
int prime[N],vis[N],cnt;
int sum[N];
void init(int n){
    for(int i=2;i<=n;i++){
        if(!vis[i])prime[cnt++]=i;
        for(int j=0;prime[j]*i<=n;j++){
            vis[prime[j]*i]=1;
            if(i%prime[j]==0)break;
        }
    }
}
int get(int n,int p){
    int res=0;
    while(n){
        res+=n/p;
        n/=p;
    }
    return res;
}
vector<int> mul(vector<int>a,int b){
    vector<int>c;
    int t=0;
    for(int i=0;i<a.size();i++){
        t+=a[i]*b;
        c.push_back(t%10);
        t/=10;
    }
    while(t){
        c.push_back(t%10);
        t/=10;
    }
    return c;
}
int main(){
    int a,b;
    cin>>a>>b;
    init(a);
    for(int i=0;i<cnt;i++){
        int p=prime[i];
        sum[i]+=get(a,p)-get(b,p)-get(a-b,p);
    }
    vector<int>res;
    res.push_back(1);
    for(int i=0;i<cnt;i++){
        for(int j=0;j<sum[i];j++){
            res=mul(res,prime[i]);
        }
    }
    for(int i=res.size()-1;i>=0;i--)cout<<res[i];
    return 0;
}

 

标签:组合,int,res,long,using,include
From: https://www.cnblogs.com/hxss/p/17371102.html

相关文章

  • 验证码,发送短信验证码,校验确认密码和密码,密码需要数字字母特殊字符任选2种组合
    密码需要数字字母特殊字符任选2种组合constvalidatePwd=(rule,value,callback)=>{constreg=/(?!^(\d+|[a-zA-Z]+|[~!@#$%^&*?]+)$)^[\w~!@#$%^&*?]{8,32}$/if(reg.test(value)==true){callback()}else{callback(newError(&#......
  • 树上组合计数
    主要来讲一讲树上的一些有关排列组合计数的问题。树上拓扑序给定一棵包含\(n\)个节点,以\(1\)为根的树。求树上拓扑序个数,即求有多少种排列方式,满足每个节点的父亲排在他前面。\(1\len\le10^6\)显然,如果没有任何限制,整棵树的方案数为\(n!\)。对于一棵以\(x\)为节点......
  • 经典数学组合题——西尔维斯特问题
    题目:在一个平面内有n(n>=3)个不完全共线的点,求证:则该平面内至少存在一条线恰好穿过其中两点证明:考查这个平面上每个至少经过两点的边以及对于一条边,不在该边上的点到边的最短长度。考虑上面最短长度中最短的一条边和一个点则该边恰好经过两个点证明如下......
  • 经典数学组合题(抽屉原理)
    题目:任意mn+1个不同的数排成一列,求证:要么存在m+1项递增数列,要么存在n+1项递减数列一、分析为什么要任意mn+1个数呢?是不是说明mn个数存在不满足的情况?我们可以先尝试寻找mn个数的情况我们发现:n,n-1,...,1,  2n,2n-1,...,n-1,  ......,  mn,mn-1,...,(m-1......
  • PMP-06-项目组合管理和醒目集管理
    一、项目组合是为了实现战略目标而组合在一起管理的项目,项目集、子项目组合和运营工作。二、项目集是一组相互关联且被协调管理的项目子项目集和项目集活动。三、项目组合管理的工作可以分为几个部分,包括业务战略、活动、项目组合、战略平衡、批准授权,项目监控。四、项目集管......
  • 十三:组合模式:优雅的组织结构
    a.组合模式解读组合模式是一种结构型设计模式,它允许将对象组织成树形结构,以表示“部分-整体”的层次关系。这种模式让客户端可以统一对待单个对象和组合对象,简化了代码的复杂度。在现实生活中,我们经常会遇到这种需求,如文件系统、组织结构等。b.亲身实践:组合模式实现为了更好地......
  • 关于组合
    网课里将组合比喻成另一半,继承则是父子之间的继承。组合这玩意,怎么看着这么想单纯地调用呢。就是调用类,而且还可以调用多个,也就是组合多个。Studentstudent=newStudent();然后继承怎么用,在前面加个student.就可了 ......
  • #yyds干货盘点# LeetCode程序员面试金典:组合总和 II
    题目:给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。candidates 中的每个数字在每个组合中只能使用 一次 。注意:解集不能包含重复的组合。  示例 1:[10,1,2,7,6,1,5]8示例 2:输入:candidates=[......
  • 组合计数
    组合数\(C^m_n\)=\(\dfrac{n(n-1)(n-2)\cdots(n-m+1)}{m!}\)=\(\dfrac{n!}{m!(n-m)!}\)\(C^m_n\)=\(C^m_{n-1}\)+\(C^{m-1}_{n-1}\)递推法求组合数求组合数Ⅰ\(\quad\)\(C^m_n\)=\(C^m_{n-1}\)+\(C^{m-1}_{n-1}\)//递推法求组合数模板//c[a][b]存储C......
  • 【完全背包的排列问题】NO377. 组合总和 Ⅳ
    [完全背包排列问题]377.组合总和Ⅳ给你一个由不同整数组成的数组nums,和一个目标整数target。请你从nums中找出并返回总和为target的元素组合的个数。题目数据保证答案符合32位整数范围。示例1:输入:nums=[1,2,3],target=4输出:7解释:所有可能的组合为:(1,......