E14 背包DP 混合背包

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;
}

 

posted @ 2023-04-10 09:58  董晓  阅读(969)  评论(0)    收藏  举报