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/
  • 相关阅读:
    Codeforces 1485C Floor and Mod (枚举)
    CodeForces 1195D Submarine in the Rybinsk Sea (算贡献)
    CodeForces 1195C Basketball Exercise (线性DP)
    2021年初寒假训练第24场 B. 庆功会(搜索)
    任务分配(dp)
    开发工具的异常现象
    Telink MESH SDK 如何使用PWM
    Telink BLE MESH PWM波的小结
    [LeetCode] 1586. Binary Search Tree Iterator II
    [LeetCode] 1288. Remove Covered Intervals
  • 原文地址:https://www.cnblogs.com/lllxq/p/9038243.html
Copyright © 2011-2022 走看看