背包问题3 二维背包和分组背包

二维背包

 有总体积为V,且最大只能放质量为 M M M的背包中,存在n个物品,体积为 v i v_i vi ,价值为 w i w_i wi,质量为 m i m_i mi,求怎么放可以得到最大价值。
 总体来说就是在01背包的基础上为物品新增了一个重量的属性,代码还是比较简单,可以在我们之前的01背包的代码基础上加一层循环就ok了。并且我们至少需要一个二维数组 d p [ i ] [ j ] dp[i][j] dp[i][j]表示在背包体积为i,质量为j的情况下的最大价值。状态转移方程为
d p [ i ] [ j ] = m a x ( d p [ i ] [ j ] , d p [ i − v [ i ] ] [ j − m [ i ] ] + w [ i ] ) dp[i][j]=max(dp[i][j],dp[i-v[i]][j-m[i]]+w[i]) dp[i][j]=max(dp[i][j],dp[iv[i]][jm[i]]+w[i])

int n=1010;
int dp[n][n];
int Two_dimension_pack(vector<int>& v,vector<int>& w,vector<int>& m,int V)
{
  for(int i=0;i<v.size();i++)
  {
    for(int j=V;j>=v[i];j--)
    {
       for(int k=M;k>=m[i];m--)
       {
       if(j>=v[i]&&k>=m[i])
         dp[j][k]=max(dp[j][k],dp[j-v[i]][k-m[i]]+w[i]);
       }
    }
  }
  return dp[V][M];
}

分组背包

 有总体积为V的背包中,存在n组物品,每组物品最多只能选一个,体积为 v i , j v_{i,j} vi,j ,价值为 w i , j w_{i,j} wi,j i i i组编号, j j j是物品在组内的编号, s s s是组内数量。求怎么放可以得到最大价值。
 在01背包代码的基础上再加一层循环,判断 d p [ j ] = m a x ( d p [ j ] , d p [ j − v [ 0 ] ] + w [ 0 ] , d p [ j − v [ 1 ] ] + w [ 1 ] . . . ) dp[j]=max(dp[j],dp[j-v[0]]+w[0],dp[j-v[1]]+w[1]...) dp[j]=max(dp[j],dp[jv[0]]+w[0],dp[jv[1]]+w[1]...)
 多重背包可以视为分组背包的一个特殊的情况,其每组内元素相同,所以他可以进行二进制优化,单调队列优化,但分组背包只能老老实实的进行三层循环。

int n=1010;
int dp[n];
int Group_pack(vector<int>& v,vector<int>& w,int V)
{
  for(int i=0;i<v.size();i++)
  {
    for(int j=V;j>=v[i];j--)
    {
       for(int k=0;k<s;k++)
       {
       if(j>=v[k])
         dp[j]=max(dp[j],dp[j-v[k]]+w[k]);
       }
    }
  }
  return dp[V];
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值