多重背包问题优化
备忘录
把集合划分成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,...,j−2×v,j−v,j 对于每一处来说
这里的rrr应该是jmod vj \mod vjmodv ,最差rrr是j−k∗vj-k*vj−k∗v
while(hh<=tt&&q[hh]<k-s*v) hh++;
q[hh]≤k−s∗vq[hh] \leq k-s*vq[hh]≤k−s∗v代表着 当前队列头已经超出了窗口 当前长度减去总长度得到了末尾的长度,从此判断队头出队没有
(k-q[hh])/v*w
(k−q[hh])÷v=(x×v)÷v(k-q[hh])\div v = (x\times v)\div v(k−q[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;
}
本文介绍了如何通过改进搜索策略,优化多重背包问题的求解过程,详细探讨了将集合划分为v类并调整枚举顺序的方法,以及如何利用队列技巧控制窗口长度。通过代码实例展示了如何在实际中应用这些优化技巧来提升算法效率。
256

被折叠的 条评论
为什么被折叠?



