P1782 旅行商的背包(多重背包基础)
单调队列优化多重背包,并暴力求出 \(f'(x)\) 表示奇货的数组。
时间复杂度 \(O(nC+mC^2)\)。
#include<bits/stdc++.h>
using namespace std;
const int N=10009,M=10009,K=10;
typedef long long ll;
int n,m,V,a[K],b[K],c[K],ff,tt;
ll dp[M],dp2[M],q[M],val[M],ans;
inline ll f(int i,ll x){
return x*x*a[i]+x*b[i]+c[i];
}
int main(){
scanf("%d%d%d",&n,&m,&V);
for(int i=1,w,v,k;i<=n;i++){
scanf("%d%d%d",&w,&v,&k);
for(int mod=0;mod<w;mod++){
ff=tt=1,q[1]=0,val[1]=dp[mod];
for(int num=1;num*w+mod<=V;num++){
while(ff<=tt&&num-q[ff]>k) ++ff;
while(ff<=tt&&val[tt]<=dp[num*w+mod]-num*v) --tt;
q[++tt]=num,val[tt]=dp[num*w+mod]-num*v;
dp[num*w+mod]=val[ff]+num*v;
}
}
}
for(int i=1;i<=m;i++)
scanf("%d%d%d",&a[i],&b[i],&c[i]);
for(int i=1;i<=m;i++) for(int j=V;j>=0;j--) for(int k=0;k<=j;k++)
dp2[j]=max(dp2[j],dp2[j-k]+f(i,k));
for(int i=0;i<=V;i++) ans=max(ans,dp[i]+dp2[V-i]);
printf("%lld\n",ans);
return 0;
}

浙公网安备 33010602011771号