因为这有个时间的限制 并且 求的时间都是前缀和
那么 我们可以根据时间将排序
因为题中没有修改可以直接用背包预处理出答案
但是因为题目ci mi<=1e9 vi<=300
所以发现不能直接背包
发现vi很小 每个商品只能被选一次 能达到的最大的价值就是n*n
因为vi越大 费用单调不减 就可以二分求
#include<bits/stdc++.h> using namespace std; #define ll long long #define C getchar()-48 inline ll read() { ll s=0,r=1; char c=C; for(;c<0||c>9;c=C) if(c==-3) r=-1; for(;c>=0&&c<=9;c=C) s=(s<<3)+(s<<1)+c; return s*r; } const int N=310,M=1e5+10,inf=1e9+10; int n,m; struct xin{ int c,v,t; }a[N]; int c[N],v[N],t[N]; int ans[N][M];// 位置 预算 inline bool pd(xin a,xin b) { return a.t<b.t; } int main() { freopen("market.in","r",stdin); freopen("market.out","w",stdout); n=read(),m=read(); for(int i=1;i<=n;i++) a[i].c=read(),a[i].v=read(),a[i].t=read(); sort(a+1,a+1+n,pd); for(int i=1;i<=n;i++) c[i]=a[i].c,v[i]=a[i].v,t[i]=a[i].t; for(int i=0;i<=n;i++) for(int j=1;j<=N*N;j++) ans[i][j]=inf; for(int i=1;i<=n;i++) { int r=0; for(int j=1;j<v[i];j++) ans[i][j]=min(ans[i-1][j],c[i]); for(int j=v[i];j<=310*310;j++) ans[i][j]=min(ans[i-1][j],ans[i-1][j-v[i]]+c[i]); } for(int i=1;i<=m;i++) { int tt=read(),mm=read(); int r=upper_bound(t+1,t+1+n,tt)-t-1; int rr=upper_bound(ans[r]+1,ans[r]+1+300*300,mm)-ans[r]-1; printf("%d\n",rr); } return 0; }