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

背包问题(未完成)

时间:2019-04-30 21:54:26      阅读:140      评论:0      收藏:0      [点我收藏+]

标签:01背包   完全背包   最大的   dal   转移   情况下   状态   line   简单   

01背包:
每件物品都有它的价值和体积,你的背包有一定容量,如何能获取最大价值?

第一行有2个整数分别表示容量和物品数(n)
接下来n行每两个数个分别代表一个物体的体积和价值

很显然,每种物品只能拿一件

当然你也可以不拿

如果拿(前提是有足够空间),就相当于背包少了v[i]的体积,多了c[i]的价值,

不拿的话(没有空间)就是上一个物品占用当时最大的体积的价值

一层循环枚举每一个物品

  二层循环枚举可用的最大体积(为什么这么说呢?,因为一个物体的体积如果是5,那么只剩2肯定装不下)

    如果能装下(c代表价值v代表枚举体积)

      f[i][v]=max(f[i-1][v],f[i-1][v-w[i]]+c[i]);

    否则

       f[i][v]=f[i-1][v];//只能跟前面一样

注意,枚举的v是指最大占用v体积的情况下获得最大的价值

v一定要倒着枚举(从最大体积开始到1结束)

因为01背包只能选一个,你在选择v-w[i]时,f[i-1][v-w[i]]其中一定没有选过i,应该很容易理解吧.

 

完全背包:
每件物品都有它的价值和体积但每件物品可以无限拿,你的背包有一定容量,如何能获取最大价值?

第一行有2个整数分别表示容量和物品数(n)
接下来n行每两个数个分别代表一个物体的体积和价值

很显然,每种物品可以拿无数件

当然你也可以不拿

如果拿(前提是有足够空间),就相当于背包少了v[i]的体积,多了c[i]的价值,

不拿的话(没有空间)就是上一个物品占用当时最大的体积的价值

我们先讲一种便于理解的方法,即:
加一重循环枚举个数k

当然,依然不能超出背包限制

状态转移方程f[ i][v] = max{ f[i][v],f[ i-1 ][ j - k*v[i]]+k* c[i]};

这应该每位dalao和像我一样的蒟蒻都能明白吧

 

然后明白了就可以上一种玄学一的点了

一层循环枚举每一个物品

  二层循环枚举可用的最大体积

    如果能装下(c代表价值v代表枚举体积)

      f[i][v]=max(f[i-1][v],f[i-1][v-w[i]]+c[i]);

    否则

       f[i][v]=f[i-1][v];//只能跟前面一样

注意,枚举的v是指最大占用v体积的情况下获得最大的价值

v一定要正着枚举(从1开始到最大体积结束)

因为完全背包可以无限选,你在选择v-w[i]时,他就有可能已经选过了.

到这里有些像我一样的蒟蒻就不懂了

我举一个生动形象的例子

背包容量为5

有1个物品,体积为2,价值为3(这么简单的例子不是因为我懒)

从5开始呢?

f[1][5]=f[0][5-2]+3;

f[1][4]=f[0][4-2]+3;

f[1][3]=f[0][3-2]+3;

f[1][2]=f[0][2-2]+3;

1和0不行

可以看出,从5到2,获得的新数分别是

f[0][3]+3

f[0][2]+3

f[0][1]+3

f[0][0]+3

没有被用过的再被利用

从1开始呢?

1和0不行

f[1][2]=f[0][2-2]+3;

f[1][3]=f[0][3-2]+3;

f[1][4]=f[0][4-2]+3;

f[1][5]=f[0][5-2]+3;

 

背包问题(未完成)

标签:01背包   完全背包   最大的   dal   转移   情况下   状态   line   简单   

原文地址:https://www.cnblogs.com/lztzs/p/10798076.html

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