D. For Gamers. By Gamers.
现有 n 种兵种,每种有单位招募代价、攻击力、生命值三个数值。需回答 m 次询问——每次询问给出魔王的攻击、生命,问在以下条件下,击败魔王至少需要花费多少代价?
- 只能选择一种兵种的士兵招募
- 任意士兵不能在战斗中死亡
- 魔王与士兵并非回合制战斗,造成伤害是连续的。
分析:因为士兵不能死亡,所以招募 k 个士兵单纯等于将其攻击力变为 k 倍。
所以浅薄观点是t*hi>De而且k*di>t*He //t是轮数,k是兵数
也就是k*hi*di>t*De*He,所以在输入时可以有一个总价值val=hi*di。
记maxval[cost]是在cost的花费下最大的价值
#include<bits/stdc++.h>
using namespace std;
long long a, ans;
long long n,b,x,y;
long long maxval[1000010];
int c, cost;
string s;
int main()
{
cin >> n >> c;
for (int i = 1; i <= n; i++)
{
cin >> cost >> x >> y;
maxval[cost] = max(x * y, maxval[cost]);//在cost的花费下最大的价值
}
//注意只能单兵种,所以只能倍增
for (int i = 1; i <= c; i++)
{
for (int j = 2; j * i <= c; j++)
{
maxval[i * j] = max(maxval[i * j], maxval[i] * j);
}
}
for (int i = 1; i <= c; i++)
{
maxval[i] = max(maxval[i], maxval[i - 1]);
}
int m;
cin >> m;
long long nedx, nedy;
long long nedval;
for (int i = 1; i <= m; i++)
{
cin >> nedx >> nedy;
nedval = nedx * nedy;
if (nedval >= maxval[c])cout << "-1 " ;//注意等于也要输出-1,是同归于尽
else
{
long long ans = upper_bound(maxval + 1, maxval + 1 + c, nedval) - maxval;
cout << ans << ' ' ;
}
}
return 0;
}
——————————————————————————————————————————
备注upper_bound用法:
查找[first, last)区域中第一个大于 val 的元素。
upper_bound (数列头地址值, 数列尾地址+1, 要找数val);
lowerbound()查找的是容器中第一个小于等于目标值的元素的位置,
而upper_bound()查找的是容器中第一个小于目标值的元素的位置就。如果容器中的元素都比目标值大则返回最后一个元素的下一个位置。