E16 背包DP 分组背包

E16 背包DP 分组背包_哔哩哔哩_bilibili

 

// 分组背包 朴素算法
#include<iostream>
#include<cstring>
using namespace std;

const int N=110;
int v[N][N],w[N][N],s[N]; // v[i,j]:第i组第j个物品的体积 s[i]:第i组物品的个数
int f[N][N]; // f[i,j]:前i组物品,能放入容量为j的背包的最大值

int main(){    
  int n,V; cin>>n>>V;
  for(int i=1;i<=n;i++){
    cin>>s[i];
    for(int j=1;j<=s[i];j++) cin>>v[i][j]>>w[i][j];
  }
  
  for(int i=1;i<=n;i++)     //物品
  for(int j=1;j<=V;j++)     //体积
  for(int k=0;k<=s[i];k++)  //同组内的物品只能选一个
    if(j>=v[i][k]) f[i][j]=max(f[i][j],f[i-1][j-v[i][k]]+w[i][k]);                 

  cout<<f[n][V];
}
// 分组背包 朴素算法 空间优化
#include<iostream>
#include<cstring>
using namespace std;

const int N=110;
int f[N],v[N],w[N];

int main(){
  int n,V,s; cin>>n>>V;
  for(int i=1;i<=n;i++){  //物品
    cin>>s;
    for(int j=1;j<=s;j++) cin>>v[j]>>w[j];      
              
    for(int j=V;j>=1;j--) //体积
    for(int k=0;k<=s;k++) //个数
      if(j>=v[k]) f[j]=max(f[j],f[j-v[k]]+w[k]);
  }
  cout<<f[V];
}

 

P1757 通天之分组背包 - 洛谷

// 分组背包 O(nm)
#include<bits/stdc++.h>
using namespace std;

const int N=1010;
int n,m,a,b,c,mx;
int v[N][N],w[N][N],s[N]; // v[i,j]:第i组第j个物品的体积 s[i]:第i组物品的个数
int f[N]; // f[i,j]:前i组物品,能放入容量为j的背包的最大值

int main(){
  cin>>m>>n; //体积 物品
  for(int i=1;i<=n;i++){
    cin>>a>>b>>c; //体积 价值 所属组数
    v[c][++s[c]]=a;
    w[c][s[c]]=b;
    mx=max(mx,c);
  }
  
  for(int i=1;i<=mx;i++)    //
  for(int j=m;j>=1;j--)     //体积
  for(int k=0;k<=s[i];k++)  //个数
    if(j>=v[i][k]) f[j]=max(f[j],f[j-v[i][k]]+w[i][k]);                 

  cout<<f[m];
}

 

P1064 [NOIP 2006 提高组] 金明的预算方案 - 洛谷

// 分组背包 O(nm)
#include<iostream>  
using namespace std;

const int N=33000;
int n,m,v,p,q;
int zv[N],zw[N],fv[N][3],fw[N][3];
int f[N];

int main(){
  cin>>m>>n;      //m总钱数 n总个数
  for(int i=1;i<=n;i++){
    cin>>v>>p>>q; //价格 重要度 对应的主件
    if(!q){
      zv[i]=v;    //主件价格
      zw[i]=v*p;  //主件价值
    }  
    else{
      fv[q][0]++;           //附件个数
      fv[q][fv[q][0]]=v;    //fv附件价格
      fw[q][fv[q][0]]=v*p;  //fw附件价值
    }
  }
  
  for(int i=1;i<=n;i++){                //物品
    for(int j=m;j>=zv[i];j--){          //价格
      f[j]=max(f[j],f[j-zv[i]]+zw[i]);  //只选主件
      if(j>=zv[i]+fv[i][1])             //选主件+a
        f[j]=max(f[j],f[j-zv[i]-fv[i][1]]+zw[i]+fw[i][1]);
      if(j>=zv[i]+fv[i][2])             //选主件+b
        f[j]=max(f[j],f[j-zv[i]-fv[i][2]]+zw[i]+fw[i][2]); 
      if(j>=zv[i]+fv[i][1]+fv[i][2])    //选主件+a+b
        f[j]=max(f[j],f[j-zv[i]-fv[i][1]-fv[i][2]]+zw[i]+fw[i][1]+fw[i][2]);  
    }
  }
  cout<<f[m]; 
}

 

posted @ 2023-04-10 10:01  董晓  阅读(967)  评论(1)    收藏  举报