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;
}

 

posted @ 2017-07-22 23:46  冥想选手  阅读(282)  评论(0编辑  收藏  举报