前言
思路
每个雇佣兵 :
c
i
,
d
i
,
h
i
c_i,d_i,h_i
ci,di,hi
每次战斗你都可以招 单种多个雇佣兵
每个小怪 :
D
i
,
H
i
D_i,H_i
Di,Hi
考虑我们枚举每一个 i i i
那么被杀死的时间就是 h i / D h_i/D hi/D
我们需要在这个时间之前杀死这个怪
则
H
d
i
∗
x
<
h
i
D
\frac{H}{d_i*x} <\frac{h_i}{D}
di∗xH<Dhi
也就是 x > ⌊ H ∗ D h i ∗ d i ⌋ + 1 x >\lfloor \frac{H*D}{h_i*d_i} \rfloor+1 x>⌊hi∗diH∗D⌋+1
如果直接枚举显然失智
假设我们现在 招了 t t t 个
那么 ⌊ H ∗ D h i ∗ d i ⌋ + 1 < = t \lfloor \frac{H*D}{h_i*d_i} \rfloor+1 <=t ⌊hi∗diH∗D⌋+1<=t
即 H ∗ D < = t ∗ h i ∗ d i − 1 H*D <= t*h_i*d_i - 1 H∗D<=t∗hi∗di−1
因此对于每一个
c
i
c_i
ci
我们都求出最大的
h
i
∗
d
i
h_i*d_i
hi∗di
然后再枚举一下
c
i
c_i
ci的所有选取,求出最大的
t
∗
h
i
∗
d
i
−
1
t_*h_i*d_i-1
t∗hi∗di−1
最后我们再二分寻找一下答案即可
Mycode
const int N = 1010000;
int n,C,m;
ll c[N],d[N],h[N],pv[N],md[N];
void solve()
{
cin>>n>>C;
for(int i = 0 ;i<n;i++){
cin>>c[i]>>d[i]>>h[i];
pv[c[i]] = max(pv[c[i]],d[i]*h[i]); //求每个C[I] 最大的d[i]*h[i]
}
for(int i=1;i<=C+1;i++){
for(int j=i;j<=C;j+=i){
md[j] = max(md[j],(j/i)*pv[i]-1); //对于每一个c_i我们求出所有选取次数内最大的 t*h*d-1
}
}
for(int j=1;j<=C+1;j++) md[j] = max(md[j],md[j-1]); //如果我们使用了 j-1就可以干掉小怪 那么 j 就可以用j-1处理
cin>>m;
for(int i=0;i<m;i++){
ll D,H;
cin>>D>>H;
ll v = D*H;
int ans = lower_bound(md,md+C+1,v) -md; //二分查找答案
if(ans >C){
cout<<-1<<" ";
}else{
cout<<ans<<" ";
}
}
}