1. 程式人生 > 其它 >Educational Codeforces Round 125 D. For Gamers. By Gamers.

Educational Codeforces Round 125 D. For Gamers. By Gamers.

傳送門

題目大意

\(n(1\leq n\leq 3\times 10^5)\) 種單位,\(C(1\leq C\leq 10^6)\) 個金幣,只能選擇一種單位進行招募,在總花費不超過 \(C\) 的情況下,可以招募若干個,每種單位 \(i\) 有單價 \(c_{i}(1\leq c_{i}\leq C)\) , 攻擊力 \(d_{i}\) , 生命值 \(h_{i}(1\leq d_{i},h_{i}\leq 10^6)\) 。需要擊敗 \(m\) 個怪物,每個怪物 \(j\) 有攻擊力 \(D_{j}(1\leq D_{j}\leq 10^6)\), 生命值 \(H_{j}(1\leq H_{j}\leq10^{12})\)

。對於每種怪物,需要擊殺其後所有招募的單位都要存活,也就是要求擊殺怪物的時間小於怪物擊殺一個所招募單位的時間,擊殺的時間就是生命值/總的攻擊力,對於每種怪物,求滿足要求的最小花費,如果不能滿足,輸出 \(-1\)

思路

對於招募了 \(k\) 個第 \(i\) 種單位, 第 \(j\) 種怪物,滿足要求的條件為 \(\frac{H{j}}{kd_{i}}<\frac{h_{i}}{D_{j}}\) ,也就是 \(kd_{i}h_{i}>D_{j}H_{j}\) 。因為只能招募一個種單位,於是我們可以預處理出 \(B[\space]\) 為每個價格 \(kc_{i}\) 下,能夠獲得的最大 \(kd_{i}h_{i}\)

。之後令 \(b[i]=max(b[i],b[i-1])\) ,即可這樣陣列 \(b\) 便是升序的,之後我們二分找到最小的滿足要求的 \(c\) 即可。

程式碼

#include<bits/stdc++.h>
#include<unordered_map>
#include<unordered_set>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
#define all(x) x.begin(),x.end()
#define int LL
//#define lc p*2+1
//#define rc p*2+2
#define endl '\n'
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f
#pragma warning(disable : 4996)
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
const double eps = 1e-8;
const LL mod = 1000000007;
const LL MOD = 998244353;
const int maxn = 1000010;

LL N, C, M;
LL A[maxn], B[maxn], c[maxn], d[maxn], h[maxn], D[maxn], H[maxn];

void solve()
{
	for (int i = 1; i <= N; i++)
		A[c[i]] = max(A[c[i]], d[i] * h[i]);
	for (int i = 1; i <= C; i++)
	{
		if (A[i])
		{
			for (int j = 1; i * j <= C; j++)
				B[i * j] = max(B[i * j], A[i] * j);
		}
	}
	for (int i = 1; i <= C; i++)
		B[i] = max(B[i], B[i - 1]);
	for (int i = 1; i <= M; i++)
	{
		LL J = H[i] * D[i];
		LL ans = upper_bound(B + 1, B + C + 1, J) - B;
		cout << (ans > C ? -1 : ans) << ' ';
	}
	cout << endl;
}

signed main()
{
	IOS;
	cin >> N >> C;
	for (int i = 1; i <= N; i++)
		cin >> c[i] >> d[i] >> h[i];
	cin >> M;
	for (int i = 1; i <= M; i++)
		cin >> D[i] >> H[i];
	solve();

	return 0;
}