zoukankan      html  css  js  c++  java
  • [数论][组合数学]微信群

    题目描述

    众所周知,一个有着6个人的宿舍可以有7个微信群(^_^,别问我我也不知道为什么),然而事实上这个数字可以更大,因为每3个或者是更多的人都可以组建一个群,所以6个人最多可以组建42个不同的群。
    现在,已知一间宿舍有N个人,并且每至少K个人都可以组建一个微信群,那么他们最多可以组建多少个不同的微信群?

    输入

    一行两个整数N和K,表示宿舍中的人数和最少能够组建微信群的人数

    输出

    一行一个整数,即最多能组建多少个不同的微信群,由于这个数字很大,请输出对10^9+7求余后的结果

    样例输入

    6 3
    

    样例输出

    42
    

    提示

    对于30%的数据,3<=N<=10^3
    对于60%的数据,3<=N<=10^6
    对于100%的数据,3<=N<=10^9,3<=K<=10^5

    思路:要求C(n,k)+C(n,k+1)+...+C(n,n),转化为求2^n-(C(n,0)+C(n,1)+...+C(n,k-1))
    求组和数有这么几种方式:
    1.C(n,m)=n!/(n-m)!/m! (逆元求组合数——n,m不太大,而T又很大时,预处理)
    2.C(n,m)=C(n,m-1)*(n-m+1)/m (递推求组合数——n较大m不太大,而T又不大时)
    3.C(n,m)=C(n-1,m)+C(n-1,m-1)(递推求组合数——n,m不太大时,而T又很大时,预处理,不过用处似乎不大?)
    组合数的性质有:
    1.C(n,m)=C(n,n-m)
    2.C(n,0)+C(n,1)+...+C(n,n-1)+C(n,n)=2^n
     
    AC代码:
    #include <iostream>
    #include<cstdio>
    #define mod 1000000007
    typedef long long ll;
    using namespace std;
    
    ll n,k;
    
    ll qpow(ll a,ll b){
      ll ret=1;
      while(b){
        if(b&1) ret=(ret*a)%mod;
        a=(a*a)%mod;
        b>>=1;
      }
      return ret;
    }
    
    int main()
    {
        scanf("%lld%lld",&n,&k);
        ll ans=qpow(2,n);
        ll sum=1; ll tmp=1;
        for(ll i=1;i<=k-1;i++){
            tmp=tmp*(n-i+1)%mod*qpow(i,mod-2)%mod;
            sum=(sum+tmp)%mod;
        }
        ans=(ans-sum+mod)%mod;//防止出现负数
        printf("%lld
    ",ans);
        return 0;
    }
    转载请注明出处:https://www.cnblogs.com/lllxq/
  • 相关阅读:
    Myeclipse修改jdk版本流程
    web框架的前生 socket写网站
    jmeter APP接口压力测试
    BeanShell实现加密解密功能
    jmeter BeanShell的几种使用方式
    jmeter多个接口测试
    jenkins添加TPS与服务器监控变化曲线图
    Jenkins的HTML报告增加显示Throughput展示
    Jmeter 分布式部署-远程服务器的搭建与设置
    Jenkins+Jmeter配置(Linux环境)
  • 原文地址:https://www.cnblogs.com/lllxq/p/9038243.html
Copyright © 2011-2022 走看看