本蒟蒻实现了一个单调队列优化的多重背包,但是核心转移部分直接用两个循环做的。而网上大多数人均是枚举余数转移,需要用三个循环。
但是前者在一些优化之后需要 500ms,甚至跑不过我之前写的二进制分组/xk
所以,这份代码常数大在哪里?
#include<bits/stdc++.h>
using namespace std;
// #define int long long
int dp[40004],tmp[40004],n,W;
int v[101],w[101],m[101];
deque<int> q[40004];
signed main(){
ios::sync_with_stdio(0);
cin>>n>>W;
for(int i=1;i<=n;i++)cin>>v[i]>>w[i]>>m[i];
for(int i=1;i<=n;i++){
if(w[i]>W)continue;
for(int j=0;j<=w[i];j++)while(!q[j].empty())q[j].pop_front();
for(int j=0;j<=W;j++){
int qi=j%w[i];
while(!q[qi].empty()&&dp[j]-(j-qi)/w[i]*v[i]>=dp[q[qi].back()]-(q[qi].back()-qi)/w[i]*v[i])q[qi].pop_back();
q[qi].push_back(j);
while(!q[qi].empty()&&(j-q[qi].front())/w[i]>m[i])q[qi].pop_front();
tmp[j]=dp[q[qi].front()]+(j-q[qi].front())/w[i]*v[i];
}
swap(dp,tmp);
}
int maxx=0;
for(int i=1;i<=W;i++)maxx=max(dp[i],maxx);
cout<<maxx;
return 0;
}