码迷,mamicode.com
首页 > 其他好文 > 详细

7.30 背包问题

时间:2018-07-30 21:43:05      阅读:131      评论:0      收藏:0      [点我收藏+]

标签:需要   int   png   如何   inf   code   空间   ++   --   

1      01背包

问题描述:

有N件物品和一个容量为V的背包。第i件物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使价值总和最大。

基本思路 :
这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放。

顺序写:

for(int i=1;i<=n;i++)
{
    for(j=c[i];j<=v;j++)  //容量至少要大于c[i]啊,不然就只能不选i了
    {
        f[i][j]=max(f[i-1][j],f[i-1][j-c[i]]+w[i]);//选与不选中找大的那一个
    }
}

这样写要开二维数组,浪费空间

怎么节省空间呢?

观察上面的状态转移方程,可以发现

f[i][j](放前i个物品,容量为j时的最大价值)=max(f[i-1][j](不放第i个物品的上一个状态的价值),f[i-1][j-c[i]]+w[i](放了第i个物品的上一个状态的价值加上 i 物品的价值))

所以我们只要保证我们找到的都是上一个状态即可。

化简为一维数组->f[j]  显然f[j]=max (f[j],f[j-c[i]]+w[i])   显然括号里的f[j]为上一个状态,那么我们还要保证f[j-c[i]]为上一个状态,如果顺序求,求到f[j]时,f[j-c[i]]已经被更新过了,就不再是上一个状态

所以我们逆序求,保证下标小的未被更新即可

for(int i=1;i<=n;i++)
{
    for(j=v;j>=c[i];j--)
    {
        f[j]=max(f[j],f[j-c[i]]+w[i]);
    }
}

 技术分享图片

 

2  完全背包

问题描述:有编号分别为a,b,c,d的四件物品,它们的重量分别是2,3,4,7,它们的价值分别是1,3,5,9,每件物品数量无限个,现在给你个承重为10的背包,如何让背包里装入的物品具有最大的价值总和?

完全背包问题与01背包问题的区别在于每一件物品的数量都有无限个,而01背包每件物品数量只有一个。

之前对于01背包逆序求的解释还有一种,即拿完一个就没得了,f[i][j]=max(f[i-1][j],f[i-1][j-c[i]]+w[i]  (拿第i个,上一个状态只能拿前i-1个)

而完全背包拿完了还可以再拿,f[i][j]=max(f[[i-1][j]  (不拿第i个),f[i][j-c[i]]+w[i]  (拿第i个,上一个状态可能仍旧拿的是第i个)

如此对于完全背包,我们不需要保证得到的都是之前的状态,顺序求即可

for(int i=1;i<=n;i++)
{
    for(j=c[i];j<=v;j++)
    {
        f[j]=max(f[j],f[j-c[i]]+w[i]);
    }
}

 

3  多重背包

 

7.30 背包问题

标签:需要   int   png   如何   inf   code   空间   ++   --   

原文地址:https://www.cnblogs.com/raincle/p/9392542.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!