多重背包,优化

本文介绍了如何通过改进搜索策略,优化多重背包问题的求解过程,详细探讨了将集合划分为v类并调整枚举顺序的方法,以及如何利用队列技巧控制窗口长度。通过代码实例展示了如何在实际中应用这些优化技巧来提升算法效率。

多重背包问题优化

备忘录

把集合划分成v类,对于每一类,枚举顺序改变
r,r+v,r+2×v,r+3×v,...,j−2×v,j−v,jr,r+v,r+2\times v, r+3\times v, ... ,j-2\times v, j-v,jr,r+v,r+2×v,r+3×v,...,j2×v,jv,j 对于每一处来说
这里的rrr应该是jmod  vj \mod vjmodv ,最差rrrj−k∗vj-k*vjkv

while(hh<=tt&&q[hh]<k-s*v) hh++; 

q[hh]≤k−s∗vq[hh] \leq k-s*vq[hh]ksv代表着 当前队列头已经超出了窗口 当前长度减去总长度得到了末尾的长度,从此判断队头出队没有

(k-q[hh])/v*w

(k−q[hh])÷v=(x×v)÷v(k-q[hh])\div v = (x\times v)\div v(kq[hh])÷v=(x×v)÷v : 相差个数

#include<bits/stdc++.h>

using namespace std;
const int N = 2222;
const int M = 22222;
int f[N][M],q[M];
int v,w,s;
int n,m;
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>v>>w>>s;
        for(int j=0;j<v;j++){
            int hh=0,tt=-1;
            for(int k=j;k<=m;k+=v){
                while(hh<=tt&&q[hh]<k-s*v) hh++;
                f[i][k]=f[i-1][k];
                if(hh<=tt) f[i][k]=max(f[i][k],f[i-1][q[hh]]+(k-q[hh])/v*w);
                while(hh<=tt&&f[i-1][q[tt]]+(k-q[tt])/v*w<=f[i-1][k]) tt--;
                q[++tt]=k;
            }
        }
    }
    cout<<f[n][m]<<endl;
    return 0;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值