背包问题详解

背包问题

有n 种不同的物品,每个物品有两个属性,size 体积,value 价值,现在给一个容量为 w 的背包,问最多可带走多少价值的物品。

情况一:物品的价值和重量给出,物品的数量均为1,背包的容量给出,背包不一定装满。

1.定义数据变量

int n;物品的总数
int total_weigh;//背包的容量
int w[];//各个物品的重量
int v[];//各个物品的价值
int c[i][j];前i个物品放入容量为j的背包的最大价值

2.初始化

int c[i][j] = {0};

3.两个主要的for循环

for (int i = 1; i <= n; i++) {  
    for (int j = 1; j <= total_weight; j++) {  
      if (w[i] > j) {  
        // 说明第i件物品大于背包的重量,放不进去  
        c[i][j] = c[i-1][j];  
      } else {  
        //说明第i件物品的重量小于背包的重量,所以可以选择第i件物品放还是不放  
          if (c[i-1][j] > v[i]+c[i-1][j-w[i]]) {  
            c[i][j] = c[i-1][j];  
          }  
          else {  
            c[i][j] =  v[i] + c[i-1][j-w[i]];  
          }  
      }  
    }  
  }  
节省空间:一维数组
        for(int i = 1; i <= n; ++i)  
        {  
            for(int v = V; v >= w[i]; --v)  //背包的重量从大到小,从而避免了覆盖前面的数据 
            {  
                f[v] = max(f[v], f[v-w[i]]+p[i]);  
            }  
        }  
情况二:物品的价值和重量给出,物品的数量均为1,背包的容量给出,背包一定装满。

1.定义数据变量

int n;物品的总数
int total_weigh;//背包的容量
int w[];//各个物品的重量
int v[];//各个物品的价值
int f[i][j];前i个物品放入容量为j的背包的最大价值

2.初始化

    for (int i = 0;i <= N;i++) //枚举物品    
    {    
        for (int j = 0;j <= V;j++) //枚举背包容量    
        {    
            f[i][j] = MinNum;    (一个比较大的负数)
        }    
    }    
    for (int i = 0;i <= N;i++)    
    {    
        f[i][0] = 0;//背包容量为0时为合法状态    
    }    

3.两个循环

    for (int i = 1;i <= N;i++) //枚举物品    
    {    
        for (int j = 1;j <= V;j++) //枚举背包容量    
        {    
            f[i][j] = f[i - 1][j]; 
            if (j >= weight[i])    
            {    
                f[i][j] = max(f[i - 1][j],f[i - 1][j - weight[i]] + value[i]); 
            }    
        }    
    }   
    //通过是否为负数来判断能否装满
节省空间:一维数组
    for (int i = 1;i <= N;i++) //枚举物品    
    {    
        for (int j = V;j >= weight[i];j--) //枚举背包容量,防越界,j下限为 weight[i]    
        {    
            f[j] = max(f[j],f[j - weight[i]] + value[i]);    
        }    
    }    
情况三:物品的价值和重量给出,物品的数量为任意个,背包的容量给出,背包不一定装满。
dp[ i+1 ][ j ] = max ( dp[ i ][ j ], dp[ i +1 ][ j - ci ] + wi );

总结

  • 背包问题解决的核心问题是:如何搭配各个物品
  • 背包是否装满决定初始化的形式,如果需要装满的话,则初始化均为大负数,背包容量为0的情况初始化为1。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值