intmain(){ int _; cin >> _; for (int ts = 0; ts < _; ++ts) { int n, m; cin >> n >> m; vector<int> mem(n); vector<int> data[2]; for (int i = 0; i < n; ++i) cin >> mem[i]; for (int i = 0; i < n; ++i) { int op; cin >> op; data[op - 1].push_back(mem[i]); } sort(data[0].begin(), data[0].end(), greater<int>()); sort(data[1].begin(), data[1].end(), greater<int>()); int ans = INT_MAX; for (int i = 1; i < data[0].size(); ++i) data[0][i] += data[0][i - 1]; for (int i = 1; i < data[1].size(); ++i) data[1][i] += data[1][i - 1];
auto iter = lower_bound(data[1].begin(), data[1].end(), m); if (iter != data[1].end()) ans = min(ans, (int) (iter - data[1].begin() + 1) * 2);
iter = lower_bound(data[0].begin(), data[0].end(), m); if (iter != data[0].end()) ans = min(ans, (int) ((iter - data[0].begin() + 1)));
for (int i = 0; i < data[0].size(); ++i) { iter = lower_bound(data[1].begin(), data[1].end(), m - data[0][i]); if (iter != data[1].end()) ans = min(ans, (int) ((iter - data[1].begin() + 1) * 2 + i + 1)); }
for (int i = 0; i < data[1].size(); ++i) { iter = lower_bound(data[0].begin(), data[0].end(), m - data[1][i]); if (iter != data[0].end()) ans = min(ans, (int) ((iter - data[0].begin() + 1) + 2 * (i + 1))); } cout << (ans == INT_MAX ? -1 : ans) << endl; } }
E. Advertising Agency
大致题意
给你一组数据,要求你从中取出 k 个数据,使得这 k 个数据的之和最大,问有几种取法
题解
首先取最大必然只能从大到小取,直到取满 k 个。但是在取最后几个相同的值的时候,由于有多个选择,则可以产生多个方案。而这个方案数量很明显即为组合数。
typedeflonglong ll; constint mod = 1e9 + 7; constint N = 1100;
ll qpow(ll a, ll b){ ll res = 1; while (b) { if (b & 1) res = res * a % mod; a = a * a % mod; b >>= 1; } return res; }
ll fac[N], ifac[N];
voidinit(int siz){ fac[0] = 1; for (int i = 1; i <= siz; i++) fac[i] = i * fac[i - 1] % mod; ifac[siz] = qpow(fac[siz], mod - 2); for (int i = siz; i >= 1; i--) ifac[i - 1] = ifac[i] * i % mod; }
ll C(ll n, ll m){ if (m == 0 || n == m) return1; if (m > n) return0; if (m == 1) return n; return fac[n] * ifac[m] % mod * ifac[n - m] % mod; }
intmain(){ init(1050); int _; cin >> _; for (int ts = 0; ts < _; ++ts) { int n, k; cin >> n >> k; map<int, int> mp; for (int i = 0; i < n; ++i) { int tmp; cin >> tmp; mp[tmp]++; }
auto iter = mp.rbegin(); while (iter != mp.rend()) { if (k > iter->second) { k -= iter->second; iter++; } else { cout << C(iter->second, k) << endl; break; } } } }