P1776 宝物筛选(多重背包基础)

二进制拆分代码:

#include<bits/stdc++.h>
using namespace std;
const int N=55005;
int f[N],n,V,ans=INT_MAX;
int main(){
    scanf("%d%d",&n,&V);
    for(int i=1;i<=V+5000;i++) f[i]=1e9;
    for(int i=1,w,v;i<=n;i++){
        scanf("%d%d",&w,&v);
        for(int j=w;j<=V+5000;j++) f[j]=min(f[j],f[j-w]+v);
    }
    for(int i=V;i<=V+5000;i++) ans=min(ans,f[i]);
    printf("%d\n",ans);
    return 0;
}

单调队列朴素代码:

#include<bits/stdc++.h>
#define f(x) (f[i-1][(x)*w+mod]-(x)*v)
using namespace std;
const int N=103,M=40005;
int n,V,f[N][M];
//Deque
int a[M],ff,tt;
int main(){
    scanf("%d%d",&n,&V);
    for(int i=1,v,w,k;i<=n;i++){
        scanf("%d%d%d",&v,&w,&k);
        for(int mod=0;mod<w;mod++){
            //这里要注意设定 f[i-1][mod] 的初始值,下一轮要用。
            ff=tt=1,a[1]=0,f[i][mod]=f[i-1][mod];
            for(int num=1;num*w+mod<=V;num++){
                while(ff<=tt&&num-a[ff]>k) ++ff;
                //当前这个物体可能非常唐,可以一个不要,要和 f[i-1][mod+num*w] 取 max。
                f[i][mod+num*w]=max(f[i-1][mod+a[ff]*w]+v*(num-a[ff]),f[i-1][mod+num*w]);
                while(ff<=tt&&f(num)>=f(a[tt])) --tt;
                a[++tt]=num;
            }
        }
    }
    printf("%d\n",f[n][V]);
    return 0;
}

压缩空间被迫在队列里存一个值进去。
这个版本能跑赢二进制优化。

#include<bits/stdc++.h>
using namespace std;
const int M=40005;
int n,V,f[M];
//Deque
int a[M],val[M],ff,tt;
int main(){
    scanf("%d%d",&n,&V);
    for(int i=1,v,w,k;i<=n;i++){
        scanf("%d%d%d",&v,&w,&k);
        for(int mod=0;mod<w;mod++){
            ff=tt=1,a[1]=0,val[1]=f[mod];
            for(int num=1;num*w+mod<=V;num++){
                while(ff<=tt&&num-a[ff]>k) ++ff;
                while(ff<=tt&&f[num*w+mod]-num*v>=val[tt]) --tt;
                a[++tt]=num,val[tt]=f[num*w+mod]-num*v;
                //要是 num 把 a[ff] 顶替掉了就说明不取当前物品最优。
                //这里只能用 val,因为 f 已经被覆盖了。
                //val[ff]+v*a[ff]+v*(num-a[ff])=val[ff]+v*num
                f[mod+num*w]=val[ff]+v*num;
            }
        }
    }
    printf("%d\n",f[V]);
    return 0;
}
posted @ 2026-02-13 18:24  2025ing  阅读(0)  评论(0)    收藏  举报