E10 背包DP 多重背包 二进制优化

视频链接:https://www.bilibili.com/video/BV1MA41177cg/

#include <iostream>
#include <algorithm>
using namespace std;

const int N=210;
int n, m;
int v[N], w[N], s[N];
int f[N][N];

int main(){
  scanf("%d%d",&n,&m);
  for(int i=1; i<=n; i++) 
    scanf("%d%d%d",&v[i],&w[i],&s[i]);  //费用,价值,数量
  
  for(int i=1; i<=n; i++)               //阶段:物品
  for(int j=0; j<=m; j++)               //状态:体积
  for(int k=0; k<=s[i]&&k*v[i]<=j; k++) //决策:个数
    f[i][j]=max(f[i][j],f[i-1][j-k*v[i]]+k*w[i]);
    
  printf("%d\n",f[n][m]);
}
#include <iostream>
#include <algorithm>
using namespace std;

const int N=210;
int n, m;
int v[N], w[N], s[N];
int f[N];

int main(){
  scanf("%d%d",&n,&m);
  for(int i=1; i<=n; i++) 
    scanf("%d%d%d",&v[i],&w[i],&s[i]);  //费用,价值,数量
  
  for(int i=1; i<=n; i++)               //阶段:物品
  for(int j=m; j>=v[i]; j--)            //状态:体积
  for(int k=0; k<=s[i]&&k*v[i]<=j; k++) //决策:个数
    f[j]=max(f[j],f[j-k*v[i]]+k*w[i]);
    
  printf("%d\n",f[m]);
}
#include<iostream>
using namespace std;

const int N=2005; //2000<2^12
int n,m;
int v1,w1,s;
int v[N*12],w[N*12];
int f[N];

int main(){
  cin>>n>>m;
  // 二进制拆分
  int num=1; 
  for(int i=1;i<=n;i++){
    cin>>v1>>w1>>s;
    for(int j=1;j<=s;j<<=1){
      v[num]=j*v1; w[num++]=j*w1;
      s-=j;
    }
    if(s) v[num]=s*v1, w[num++]=s*w1;
  }
  // 01背包
  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]);  
  cout<<f[m];
}

Luogu P1776 宝物筛选

// 二进制分组优化
#include<iostream>
using namespace std;

const int N=100005;
int n,m,a,b,s;
int v[N],w[N];
int f[N];

int main(){
  cin>>n>>m;
  
  int cnt=0; 
  for(int i=1;i<=n;i++){
    cin>>b>>a>>s;
    for(int j=1;j<=s;j<<=1){
      v[++cnt]=j*a; w[cnt]=j*b;
      s-=j;
    }
    if(s) v[++cnt]=s*a, w[cnt]=s*b;
  }

  for(int i=1;i<=cnt;i++) 
    for(int j=m;j>=v[i];j--)
      f[j]=max(f[j],f[j-v[i]]+w[i]);
  cout<<f[m];
}

 

posted @ 2023-04-10 09:23  董晓  阅读(641)  评论(1编辑  收藏  举报