zoukankan      html  css  js  c++  java
  • D. Time to go back(思维)

    题目链接:http://codeforces.com/gym/100952/problem/D

    题目大意:n个礼物,m个人,要给m个人中的k个人买大于等于d的礼物,其他人随意,问你选择礼物的方案数(不是分配礼物的方案数)。

    具体思路:一开始我的思路,先输出大于等于k的礼物的个数ans,然后再直接计算C(ans,k)*C(n-ans,m-k)就可以了。但是这样会出现重复计算的情况。比如说,4,5,6,7都满足情况,如果是按照我的思路的话,(4,5,6)和(4,6,5)是不同的,但是我们求的是选择礼物的方案数,不是分配数,所以这两个属于一个方案。然后就问了一下别人的思路,我们每一次选取t(t>=k)个满足大于d的值,然后剩下的从小于d的里面选,当t到达大于d的个数的时候,或者人数够了的时候停止,这样就能保证每一种方案里面,大于d的个数就肯定不同了。

    感谢张明学长和lhk的精彩解释。

    AC代码:

     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<cmath>
     4 using namespace std;
     5 # define ll long long
     6 const int maxn =2e5+100;
     7 const int mod = 1e9+7;
     8 ll a[maxn];
     9 ll tmp[maxn];
    10 ll quickpow(ll t1,ll t2){
    11 ll ans=1;
    12 while(t2){
    13 if(t2&1)ans=ans*t1%mod;
    14 t2>>=1;
    15 t1=t1*t1%mod;
    16 }
    17 return ans;
    18 }
    19 ll C(ll n,ll r){
    20 if(n==r||r==0)return 1;
    21 tmp[0]=1;
    22 for(ll i=1;i<=r;i++){
    23 tmp[i]=(tmp[i-1]*(n-i+1)%mod*quickpow(i,mod-2))%mod;
    24 }
    25 return tmp[r]%mod;
    26 }
    27 int main(){
    28 int T;
    29 scanf("%d",&T);
    30 while(T--){
    31 ll n,m,k,d;
    32 scanf("%lld %lld %lld %lld",&n,&m,&k,&d);
    33 ll ans=0;
    34 for(ll i=1;i<=n;i++){
    35 scanf("%lld",&a[i]);
    36 if(a[i]>=d)ans++;
    37 }
    38 ll w=min(m,ans);//注意取min
    39 ll tot=0;
    40 for(ll  i=k;i<=w;i++){
    41 tot+=C(ans,i)*C(n-ans,m-i)%mod;
    42 tot%=mod;
    43 }
    44 printf("%lld
    ",tot%mod);
    45 }
    46 return 0;
    47 }
  • 相关阅读:
    SG函数
    贪心:zoj3953 Intervals
    山东省第四届省赛 E-Mountain Subsequences
    山东省第四届ACM程序设计竞赛A题:Rescue The Princess
    前缀和:CodeForces 932B Recursive Queries
    常用头文件和一些简单的函数
    codeforce 429D. Tricky Function (思维暴力过)
    HDU-5754 Life Winner Bo (博弈论)
    线程池的原理与实现
    运行停止一个线程
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10503093.html
Copyright © 2011-2022 走看看