题目链接
题意:
在最少的时间内并且价格在s内从m个物品中购买k个物品
题解:
如果Nura能在x天内买到k个小玩意,那么她也能在x+1天内买到这些小玩意。所以,这个答案是单调的。因此,我们可以使用二分查找来找到最小的天数。
第i天的美元汇率和英镑汇率分别存储在a、b数组中,之后输入m个w物品第一个参数是1则表示只能用美元买存放到c数组中,否则只能用英镑买存到d数组中
下面进行二分check表示前i天花最少的钱买k个物品的价格是否小于s
每天可以买任意个商品但是一个商品只能买一次,显然可以找到前mid天的最小美元和最小英镑之后依次分类×对应的商品价格。
用e数组来表示m个商品在前mid天化最少的美元mx1,与花最少的英镑mx2的代价,之后排序获得前k个代价小的商品的总和并判断是否多于总价钱s;
最后最少天数存在的话,则依次输出商品的编号与买的时间。这些⭐被存放到ve<pl> f(m)数组中。
#include <bits/stdc++.h>
using namespace std;#define fi first
#define se second
#define ve vector
#define all(x) (x).begin(), (x).end()
#define rep(i, a, b) for (int i = a; i < b; i++)
#define per(i, a, b) for (int i = a; i >= b; i--)using pl = pair<int64_t, int>;inline int red() {int x;cin >> x;return x;
}void solve() {int n = red(), m = red(), k = red(), s = red();ve<int64_t> e(m);ve<pl> f(m);ve<int> a(n), b(n), c(m), d(m);generate(all(a), red);generate(all(b), red);rep(i, 0, m) {int op = red();if (op == 1) {c[i] = red();} else {d[i] = red();}}auto check = [&](int mid, int flag) -> bool {int64_t sum = 0;int mx1 = 1e9 + 7, mx2 = 1e9 + 7, d1, d2;rep(i, 0, mid) {if (mx1 > a[i]) {mx1 = a[i];d1 = i;}if (mx2 > b[i]) {mx2 = b[i];d2 = i;}}rep(i, 0, m) {e[i] = (int64_t)c[i] * mx1 + (int64_t)d[i] * mx2;}sort(all(e));rep(i, 0, k) {sum += e[i];}if (flag) {rep(i, 0, m) {f[i] = {(int64_t)c[i] * mx1 + (int64_t)d[i] * mx2, i};}sort(all(f));rep(i, 0, k) {if (c[f[i].se]) {cout << f[i].se + 1 << ' ' << d1 + 1 << '\n';} else {cout << f[i].se + 1 << ' ' << d2 + 1 << '\n';}}}return sum <= s;};int low = 0, high = n;while (low < high) {int mid = (low + high) >> 1;if (check(mid, 0)) {high = mid;} else {low = mid + 1;}}if (check(low, 0)) {cout << low << '\n';check(low, 1);} else {cout << -1 << '\n';}
}int main() {ios_base::sync_with_stdio(false);cin.tie(nullptr);int t = 1;while (t--) {solve();}return 0;
}