题目大意

解题思路
将商店和询问按时间排序,一边dp一边回答询问。
code
using namespace std;
LL const inf=1e15;
LL const maxn=300,maxm=1e5;
LL n,m,f[maxn*maxn+10],g[maxn*maxn+10],ans[maxm+10];
struct rec{
LL c,v,t;
};
rec a[maxn+10],b[maxm+10];
bool cmp(rec x,rec y){
return x.t<y.t;
}
int main(){
//freopen("market.in","r",stdin);
//freopen("market.out","w",stdout);
freopen("d.in","r",stdin);
freopen("d.out","w",stdout);
scanf("%lld%lld",&n,&m);
fo(i,1,n)scanf("%lld%lld%lld",&a[i].c,&a[i].v,&a[i].t);
sort(a+1,a+n+1,cmp);
fo(i,1,m)scanf("%lld%lld",&b[i].t,&b[i].c),b[i].v=i;
sort(b+1,b+m+1,cmp);
LL ii=1;
fo(i,1,maxn*maxn+1)f[i]=g[i]=inf;
fo(i,1,n){
for(;(ii<=m)&&(b[ii].t<a[i].t);ii++){
LL l=0,r=maxn*maxn;
for(;l!=r;){
LL mid=(l+r+1)/2;
if(g[mid]<=b[ii].c)l=mid;
else r=mid-1;
}
ans[b[ii].v]=l;
}
fd(j,maxn*maxn,a[i].v)
f[j]=min(f[j],f[j-a[i].v]+a[i].c);
fd(j,maxn*maxn,0)
g[j]=min(g[j+1],f[j]);
}
for(;ii<=m;ii++){
LL l=0,r=maxn*maxn;
for(;l!=r;){
LL mid=(l+r+1)/2;
if(g[mid]<=b[ii].c)l=mid;
else r=mid-1;
}
ans[b[ii].v]=l;
}
fo(i,1,m)printf("%lld\n",ans[i]);
return 0;
}