python--蓝桥杯--组合数的计算

组合数的计算(3种方法)

## 组合数的计算
##1、定义
def Cnm(n,m):
    ans=1
    for i in range(1,n+1):
        ans*=i
    for i in range(1,m+1):
        ans//=i
    for i in range(1,(n-m)+1):
        ans//=i
    return ans

##2、递推公式
## Cnm=Cn-1m-1+Cn-1m
## 该方法完全不涉及阶乘计算
## 但是会产生重复计算的问题
## 递归
def Cnm_2(n,m):
    if m==0 or m==n:
        return 1
    return Cnm_2(n-1,m)+Cnm_2(n-1,m-1)
##2、递推公式(把整张表计算出来)
## 递推
def calC(n,m):
    res=[[0]*(1+n) for _ in range(1+n)]
    ## 边界条件初始化
    for i in range(1+n):
        res[i][0]=res[i][i]=1
    for i in range(2,1+n):
        for j in range(1,i//2+1):
            res[i][j]=res[i-1][j-1]+res[i-1][j]
            res[i][i-j]=res[i][j]
    return res
##3、公式变形
def calC_2(n,m):
    ans=1
    for i in range(1,m+1):
        ans=ans*(n-m+i)//i
    return ans

print(Cnm(4,2))
print(Cnm_2(4,2))
res=calC(4,4)
print(res[4][2])
print(calC_2(4,2))

Cnm%p的计算(4种方法)

##Cnm%p的计算
## 法一、通过递推公式计算
## 递归
def calC_1(n,m,p):
    if m==0 or m==n:
        return 1
    return (calC_1(n-1,m-1,p)+calC_1(n-1,m,p))%p
## 递推
def calC_2(n,m,p):
    res=[[0]*(1+n) for _ in range(1+n)]
    ## 初始化
    for i in range(1+n):
        res[i][0]=res[i][i]=1
    for i in range(2,1+n):
        for j in range(i//2+1):
            res[i][j]=(res[i-1][j-1]+res[i-1][j])%p
            res[i][i-j]=res[i][j]
    return res

##法二、根据定义计算
## 运用到N!的一个问题中cal函数

##法三、定义变形

##法四、Lucas定理
def C(n,m):
    if m==0 or m==n:
        return 1
    return C(n-1,m-1)+C(n-1,m)
p=5
def Lucas(n,m):
    global p
    if m==0:
        return 1
    return C(n%p,m%p)*Lucas(n//p,m//p)%p
print(calC_1(4,2,5))
res=calC_2(4,4,5)
print(res[4][2])
print(Lucas(4,2))

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值