「luogu1782 」旅行商的背包
单调队列优化多重背包
要注意更新dp数组语句的位置
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define R register 4 using namespace std; 5 const int N=20010; 6 int n,m,cap,v[N],w[N],d[N],a[N],b[N],c[N],ans=0,cnt[N]; 7 ll f[N],q[N]; 8 inline int read(){ 9 int x=0,w=1;char c=0; 10 while(c<'0'||c>'9'){if(c=='-') w=-1;c=getchar();} 11 while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-'0',c=getchar(); 12 return x*w; 13 } 14 int main(){ 15 int t,h,nxt; 16 n=read(),m=read(),cap=read(); 17 for(R int i=1;i<=n;i++) v[i]=read(),w[i]=read(),d[i]=read(); 18 for(R int i=1;i<=m;i++) a[i]=read(),b[i]=read(),c[i]=read(); 19 for(R int i=1;i<=n;i++) 20 for(R int j=0;j<v[i];j++) 21 for(R int k=0,head=0,tail=0;k*v[i]+j<=cap;k++){ 22 int nxt=f[k*v[i]+j]-k*w[i]; 23 if(k-cnt[head]>d[i]) head++; 24 while(head<tail&&q[tail-1]<nxt) tail--; 25 q[tail]=nxt,cnt[tail++]=k; 26 f[k*v[i]+j]=q[head]+k*w[i]; 27 } 28 for(R int i=1;i<=m;i++) 29 for(R int j=cap;j>=0;j--) 30 for(R int k=0;k<=j;k++) f[j]=max(f[j],f[j-k]+a[i]*k*k+b[i]*k+c[i]); 31 printf("%lld",f[cap]); 32 return 0; 33 }