D-DTime
limit:MS
Memory Limit:262144KB
64bit IO Format:%i64d &%i64u SubmitStatusPracticeGym 100952D
Description
Standard Input/output
Statements
You are been out of Syria for a long time, and you recently decided to come back. You remember this you had M friends there and since you is a generous man/woman you want to buy a gift for each of the them, So-went to a gift store, which has N-gifts, each of the them has a price.
You had a lot of money so you don ' t has a problem with the sum of gifts ' prices which you'll buy, but you have K close fr Iends among
Your M friends you want their gifts to being expensive so the price of each of the them are at least D.
Now is wondering, how do many different ways can you choose the gifts?
Input
The input would start with a single integer T, the number of test cases. Each test case consists of lines.
The first line'll has four integers N, M, K, D (0 ? ≤?). N, M ≤ 0, ≤? K . ≤ 0 ? ≤? D. ≤ 500).
The second line would have N positive integer number and the price of each gift.
The gift price is ? ≤ ? 500.
Output
Print one line for all test case, the number of different ways to choose the gifts (there'll be a always one-off at least To choose the gifts).
As the number of ways can too large, print it modulo 1000000007.
Sample Input
Input
25 3 2 100150 30 100 70 1010 5 3 50100 50 150 10 25 40 55 300 5 10
Output
3126
Source
UESTC Summer Training #21
Gym 100952D
My Solution
Combinatorial studies
There are n gifts, m friends, of whom K is a good friend, to buy a gift of price greater than D
The number of gifts for >= D is CNT
If use C[cnt][k] * C[n-k][m-k] is obviously wrong, because here before the choice of price >= D, the back to the ordinary good friend choose the gift of the time will also be selected, so the total number of gifts to buy a lot of repetition
So it should be sorted by step (price >= D and < D separately, so it won't be the same gift selected 2 times)
First C[cnt][k] * c[n-cnt][m-k];
Then C[CNT][K + 1] * c[n-cnt][m-k-1]
Next C[cnt][k + 2] * c[n-cnt][m-k-2]
......
Until K + 1 = = CNT or m-k-1 < 0//where if k + 1 = = CNT is selected, and M-k-1 < 0 are all selected price >= D
Complexity O (T * N)
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm>using namespace Std;typedef Long Long ll;const int MAXN = 2*1e2 + 8;const ll Hash = 1000000007;inline ll mod (ll a) {return a-(A/hash) *hash;} LL C[MAXN][MAXN], val[maxn];inline void GetC () {memset (c, 0, sizeof C); for (int i = 0; i < MAXN; i++) {c[i][0] = 1; for (int j = 1; J <= I; j + +) {C[i][j] = mod (c[i-1][j-1] + c[i-1][j]); }}}inline BOOL CMP (ll A, ll b) {return a > B;} int main () {#ifdef LOCAL freopen ("A.txt", "R", stdin); Freopen ("B.txt", "w", stdout); #endif//LOCAL GetC (); int T, N, M, K, D, CNT; LL ans; scanf ("%d", &t); while (t--) {cnt = 0; ans = 0; scanf ("%d%d%d%d", &n, &m, &k, &d); for (int i = 0; i < n; i++) {scanf ("%i64d", &val[i]); } sort (val, Val + N, CMP); for (int i = 0; i < n; i++) {if (Val[i] < D) Break else cnt++; }//cout<<cnt<<endl; cout<<c[n-k][m-k]<<endl; for (int i = k; I <= cnt; i++) {if (n-cnt = = 0) break; if (M-i < 0) break; ans = mod (ans + mod (c[cnt][i] * c[n-cnt][m-i)); } if (n-cnt = = 0) ans = c[cnt][m]; ans = mod (c[cnt][k] * c[n-k][m-k]); if (CNT < K | | n < m) printf ("0\n"); else printf ("%i64d\n", ans); } return 0;}
Thank you!
------ from Prolights
Gym 100952D time-to-go back combinatorics, Yang Hui triangle preprocessing combined number