• 2015 HIAST Collegiate Programming Contest D


    You have been out of Syria for a long time, and you recently decided to come back. You remember that you have M friends there and since you are a generous man/woman you want to buy a gift for each of them, so you went to a gift store that have N gifts, each of them has a price.

    You have a lot of money so you don't have a problem with the sum of gifts' prices that you'll buy, but you have K close friends among your M friends you want their gifts to be expensive so the price of each of them is at least D.

    Now you are wondering, in how many different ways can you choose the gifts?

    Input

    The input will start with a single integer T, the number of test cases. Each test case consists of two lines.

    the first line will have four integers N, M, K, D (0  ≤  N, M  ≤  200, 0  ≤  K  ≤  50, 0  ≤  D  ≤  500).

    The second line will have N positive integer number, the price of each gift.

    The gift price is  ≤  500.

    Output

    Print one line for each test case, the number of different ways to choose the gifts (there will be always one way at least to choose the gifts).

    As the number of ways can be too large, print it modulo 1000000007.

    Example

    Input
    2
    5 3 2 100
    150 30 100 70 10
    10 5 3 50
    100 50 150 10 25 40 55 300 5 10
    Output
    3
    126

    解题思路:
    就是一道很容易的高中排列组合题,放在高中是送分题,结果被卡到比赛结束。
    有n个商品,要选m个送人,其中k各人要价格大于d的商品,问有多少种分法。 假设有10个人,送5个,3个要价格高的,
    那么有三种情况:
    1.贵的选三个,不贵的选两个:c53*c52
    2.贵的选四个,不贵的选一个:c54*c51
    3.贵的选五个:c55
    分法就是 c53*c52+c54*c51+c55
    之前写的时候一直不对,要用杨辉三角解,如果直接除的话,分子是很大的必须要取模,但取完模后,分子会小于分母,然后数值就为0,而杨辉三角就没有这种顾虑了,只有加法。。

    实现代码:
    #include<bits/stdc++.h>
    using namespace std;
    const int inf = 1e9+7;
    #define ll long long
    const int  maxx = 2*1e2+9;
    ll mod(ll x){
        return x-(x/inf)*inf;
    }
    
    int main()
    {
        int i,j,n,m,k,d,a,t,cnt;
        ll c[maxx][maxx],ans;
        memset(c,0,sizeof(c));
        for(i=0;i<maxx;i++){
            c[i][0] = 1;
            for(j=1;j<=i;j++)
            c[i][j] = mod(c[i-1][j-1]+c[i-1][j]);
        }
        ios::sync_with_stdio(0);
        cin.tie(0);
        cin>>t;
        while(t--){
            ans = 0;cnt=0;
            cin>>n>>m>>k>>d;
            for(i=0;i<n;i++){
                cin>>a;
                if(a>=d)
                    cnt++;
            }
            //cout<<ans<<endl;
            for(i=k;i<=cnt;i++){
                if(n-cnt==0) break;
                if(m-i<0) break;
                else
                    ans=mod(ans+mod(c[cnt][i]*c[n-cnt][m-i]));
                    //cout<<c[cnt][i]<<" "<<c[n-cnt][m-i]<<endl;
                    //cout<<ans<<endl;
            }
            if(n - cnt == 0) ans = c[cnt][m];
            //ans = mod(C[cnt][k] * C[n - k][m - k]);
            if(cnt < k || n < m)
            cout<<"0"<<endl;
            else cout<<ans<<endl;
        }
        return 0;
    }
  • 相关阅读:
    2015.7.23 开始记录一些学习情况
    poj 3299 java
    在线编辑~
    MATLAB加载数据来绘图《原创翻译Loading Data into MATLAB for Plotting》
    【转载】matlab的reshape函数的作用
    (转载)CUDA 6.0 安装及配置( WIN7 64位 / 英伟达G卡 / VS2010 )
    简单文本处理
    【转】CUDA与二维动态数组
    《转载》 cpp文件调用CUDA .cu文件实现显卡加速相关编程
    cuda_opencv之向量相加
  • 原文地址:https://www.cnblogs.com/kls123/p/7223308.html
Copyright © 2020-2023  润新知