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;
}
posted @ 2026-02-13 23:02  2025ing  阅读(0)  评论(0)    收藏  举报