E14 背包DP 混合背包_哔哩哔哩_bilibili
T627139 混合背包 - 洛谷
// 混合背包+二进制优化
#include<bits/stdc++.h>
using namespace std;
int n,m;
int num,v[75000],w[75000]; //5000*log10000
int f[5005];
int main(){
scanf("%d %d",&n,&m);
for(int i=1,v1,w1,s; i<=n; i++){
scanf("%d%d%d",&v1,&w1,&s);
if(s==-1) s=1;
if(s==0) s=5000;
for(int j=1; j<=s; j<<=1){
v[++num]=j*v1;
w[num]=j*w1;
s-=j;
}
if(s){
v[++num]=v1*s;
w[num]=w1*s;
}
}
for(int i=1; i<=num; i++){
for(int j=m; j>=v[i]; j--)
f[j]=max(f[j],f[j-v[i]]+w[i]);
}
printf("%d",f[m]);
return 0;
}
// 混合背包+单调队列优化
#include<bits/stdc++.h>
using namespace std;
int n,m;
int f[5005],g[5005];
void ZeroOnePack(int v,int w){
for(int j=m; j>=v; j--)
f[j]=max(f[j],f[j-v]+w);
}
void CompletePack(int v,int w){
for(int j=v; j<=m; j++)
f[j]=max(f[j],f[j-v]+w);
}
void MultiplePack(int v,int w,int s){
memcpy(g,f,sizeof(f));
for(int y=0; y<v; y++){
deque<int> q;
for(int x=0; x*v+y<=m; x++){
while(!q.empty() && q.front()<x-s) q.pop_front();
while(!q.empty() && g[q.back()*v+y]-q.back()*w<g[x*v+y]-x*w) q.pop_back();
q.push_back(x);
f[x*v+y]=(g[q.front()*v+y]-q.front()*w)+x*w;
}
}
}
int main(){
cin>>n>>m;
for(int i=1,v,w,s; i<=n; i++){
scanf("%d %d %d",&v,&w,&s);
if(s==-1) ZeroOnePack(v,w); //01背包
else if(s==0) CompletePack(v,w); //完全背包
else MultiplePack(v,w,s); //多重背包
}
cout<<f[m];
}
P1833 樱花 - 洛谷
// 混合背包+二进制优化
#include<bits/stdc++.h>
using namespace std;
int h1,m1,h2,m2,n,m;
int num,v[100005],w[100005]; //10000*log1000
int f[1005];
int main(){
scanf("%d:%d %d:%d %d",&h1,&m1,&h2,&m2,&n);
m=(h2*60+m2)-(h1*60+m1);
for(int i=1,v1,w1,s; i<=n; i++){
scanf("%d%d%d",&v1,&w1,&s); //时间,价值,个数
if(!s) s=1000; //最多1000次
for(int j=1; j<=s; j<<=1){
v[++num]=j*v1;
w[num]=j*w1;
s-=j;
}
if(s){
v[++num]=v1*s;
w[num]=w1*s;
}
}
for(int i=1; i<=num; i++){
for(int j=m; j>=v[i]; j--)
f[j]=max(f[j],f[j-v[i]]+w[i]);
}
printf("%d",f[m]);
return 0;
}