zoukankan      html  css  js  c++  java
  • 扔硬币

    扔硬币

     题解:

    1.如果(left ( m+k ight )> n),那么就很明显答案为0;

    2.根据条件概率:则题目就是求,在至少有(m)枚硬币是反面的情况下,恰好有(k)枚硬币是正面的概率。那么就可以设(A)为至少有(m)枚硬币是反面,(B)为恰好有(k)枚硬币是正面,答案即为(frac{Pleft ( AB ight )}{Pleft ( A ight )});恰好(k)枚硬币是正面,则(Pleft ( AB ight )=C_{n}^{k}),至少(m)枚硬币是反面,则(Pleft ( A ight )=left ( C_{n}^{0}+C_{n}^{1}+cdots +C_{n}^{n} ight )-left ( C_{n}^{0}+C_{n}^{1}+cdots +C_{n}^{m-1} ight )=2^{n}-sum_{i=0}^{m-1}C_{n}^{i}),所以答案即为:(C_{n}^{k}/left ( 2^{n}-sum_{i=0}^{m-1}C_{n}^{i} ight )(除法又可以转为求逆元))

    AC_Code:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int maxn = 1e5+10;
     5 const ll mod=1e9+7;
     6 
     7 ll n,m,k;
     8 ll F[maxn];
     9 ll qpow(ll a, ll b){//快速幂
    10     ll res=1;
    11     while( b ){
    12         if( b&1 ) res = res*a%mod;
    13         a = a*a%mod;
    14         b>>=1;
    15     }
    16     return res;
    17 }
    18 
    19 ll inv(ll x){//求逆元
    20     return qpow(x,mod-2);
    21 }
    22 
    23 void init(){
    24     F[0]=1;
    25     for(int i=1;i<=100000;i++){
    26         F[i]=F[i-1]*i%mod;
    27     }
    28 }
    29 
    30 int main()
    31 {
    32     int t;
    33     scanf("%d",&t);
    34     init();
    35     while( t-- ){
    36         scanf("%lld%lld%lld",&n,&m,&k);
    37         if( m+k>n ){
    38             printf("0
    ");
    39             continue;
    40         }
    41         ///C(n,k):n!/(k!*(n-k)!)
    42         ll up=F[n]*inv(F[k])%mod*inv(F[n-k])%mod;
    43         //2^n-sum(C(n,0)~C(n,m-1));
    44         ll down=qpow(2,n);
    45         ll sum=1,pre=1;
    46         for(ll i=1;i<m;i++){
    47             pre=pre*(n-i+1)%mod*inv(i)%mod;
    48             sum = (sum+pre)%mod;
    49         }
    50         down = (down-sum+mod)%mod;
    51         down = inv(down);
    52         ll ans=up*down%mod;
    53         printf("%lld
    ",ans);
    54     }
    55     return 0;
    56 }
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int maxn = 1e5+10;
     5 const ll mod=1e9+7;
     6 
     7 ll n,m,k;
     8 ll F[maxn];//F[i]:1~i的阶乘
     9 ll Inv[maxn];//Inv[i]:i的逆元
    10 ll Finv[maxn];//Finv[i]:F[i]的逆元
    11 
    12 ll qpow(ll a, ll b){//快速幂
    13     ll res=1;
    14     while( b ){
    15         if( b&1 ) res = res*a%mod;
    16         a = a*a%mod;
    17         b>>=1;
    18     }
    19     return res;
    20 }
    21 
    22 ll inv(ll x){//求逆元
    23     return qpow(x,mod-2);
    24 }
    25 
    26 void init(){
    27     F[0]=F[1]=1;
    28     Finv[0]=Finv[1]=1;
    29     Inv[0]=Inv[1]=1;
    30     for(int i=2;i<=100000;i++){
    31         F[i]=1ll*F[i-1]*i%mod;
    32         Inv[i]=1ll*(mod-mod/i)*Inv[mod%i]%mod;
    33         Finv[i]=1ll*Finv[i-1]*Inv[i]%mod;
    34     }
    35 }
    36 
    37 ll C(ll a,ll b){//求C(a,b)
    38     if( b>a || b<0 ) return 0ll;
    39     return 1ll*F[a]*Finv[b]%mod*Finv[a-b]%mod;
    40 }
    41 
    42 int main()
    43 {
    44     int t;
    45     scanf("%d",&t);
    46     init();
    47     while( t-- ){
    48         scanf("%lld%lld%lld",&n,&m,&k);
    49         if( m+k>n ){
    50             printf("0
    ");
    51             continue;
    52         }
    53         ll up=C(n,k);//分母
    54         ll down=qpow(2,n);
    55         ll sum=1;
    56         for(int i=1;i<m;i++){
    57             sum=(sum+C(n,i))%mod;
    58         }
    59         down=(down-sum+mod)%mod;//分子
    60         ll ans=up*inv(down)%mod;
    61         printf("%lld
    ",ans);
    62 
    63     }
    64     return 0;
    65 }
  • 相关阅读:
    20201022-1 每周例行报告
    Alpha发布
    每周例行报告
    20201207-总结
    20201126-1 每周例行报告
    作业要求 20201120-1 每周例行报告
    20201112-1 每周例行报告
    作业要求 20201015-3 每周例行报告
    20200924-5 四则运算试题生成,结对
    20200924-1 每周例行报告
  • 原文地址:https://www.cnblogs.com/wsy107316/p/13308402.html
Copyright © 2011-2022 走看看