地址:https://codeforces.com/contest/1657/problem/D
思路:要使得单位 i {di,hi}能够战胜怪兽{Di,Hi},有
H
i
d
i
>
h
i
D
i
\frac{Hi}{di}>\frac{hi}{Di}
diHi>Dihi,即
h
i
∗
d
i
>
H
i
∗
D
i
hi*di > Hi*Di
hi∗di>Hi∗Di ,而x个单位i战胜怪兽而不是死掉一个单位,即
i
∗
h
i
∗
d
i
>
H
i
∗
D
i
i * hi * di > Hi * Di
i∗hi∗di>Hi∗Di
因此计算出用Ci个金币能够获得的最大战力,然后二分查找即可
计算Ci金币的最大战力,对于每个单位i,计算其1,2,3…个单位的战力来求肯定会超时,这里只需要先保存每个单位只要一个时的战力,然后ci从1到C开始遍历,每次j+=ci取最大战力即可,其中ci为战力为0的可以通过前缀求得最大战力
Code:
#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;
typedef long long LL;
const int MAX_C=1e6+5;
const int MAX_M=3e5+5;
int n,m,C;
LL a[MAX_C];
LL res[MAX_M];
int main()
{
scanf("%d%d", &n, &C);
LL ci,di,hi;
for(int i=0;i<n;++i)
{
scanf("%lld%lld%lld",&ci,&di,&hi);
a[ci]=max(a[ci],di*hi);
}
for(int i=1;i<=C;++i)
{
if(a[i]==0) continue;
for(int j=i;j<=C;j+=i)
a[j]=max(a[j],a[i]*(j/i));
}
for(int i=1;i<=C;++i)
a[i]=max(a[i],a[i-1]);
scanf("%d",&m);
int t;
for(int i=0;i<m;++i)
{
scanf("%lld%lld",&di,&hi);
ci=di*hi;
t=lower_bound(a,a+C+1,ci+1)-a;
if(t<C+1){
res[i]=t;
}else{
res[i]=-1;
}
}
for(int i=0;i<m-1;++i)
printf("%lld ",res[i]);
printf("%lld\n",res[m-1]);
return 0;
}