去掉每一个物品,在v体积下的最大获利。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<vector> #define maxn 1050 #define maxm 300500 using namespace std; int n,x,y,z,m,ans[maxm]; vector <int> linker[maxn],val[maxn],a; struct point { int l,r,v,w; point (int l,int r,int v,int w):l(l),r(r),v(v),w(w){} }; vector <point> v; void DC(int l,int r,vector <point> v,vector <int> a) { int mid=l+r>>1; vector <point> x,y; for (int i=0;i<v.size();i++) { point now=v[i]; if ((now.l==l) && (now.r==r)) { for (int j=maxn;j>=now.v;j--) a[j]=max(a[j],a[j-now.v]+now.w); } else if (now.r<=mid) x.push_back(now); else if (now.l>=mid+1) y.push_back(now); else { x.push_back(point(now.l,mid,now.v,now.w)); y.push_back(point(mid+1,now.r,now.v,now.w)); } } if (l==r) { for (int i=0;i<linker[l].size();i++) ans[linker[l][i]]=a[val[l][i]]; return; } DC(l,mid,x,a); DC(mid+1,r,y,a); } int main() { freopen("chisa.in","r",stdin); freopen("chisa.out","w",stdout); scanf("%d",&n); for (int i=1;i<=n;i++) { scanf("%d%d%d",&x,&y,&z); if (i!=1) v.push_back(point(1,i-1,x,y)); if (i!=n) v.push_back(point(i+1,n,x,y)); } for (int i=0;i<=maxn;i++) a.push_back(0); scanf("%d",&m); for (int i=1;i<=m;i++) { scanf("%d%d",&x,&y); x++; linker[x].push_back(i);val[x].push_back(y); } DC(1,n,v,a); for (int i=1;i<=m;i++) printf("%d ",ans[i]); return 0; }