背包问题(未完成)

Posted lztzs

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了背包问题(未完成)相关的知识,希望对你有一定的参考价值。

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;

 

以上是关于背包问题(未完成)的主要内容,如果未能解决你的问题,请参考以下文章

bzoj1190--梦幻岛宝珠--分层dp+01背包(未完成)

动态规划-自底向上的 0-1 背包问题

c语言背包问题,求高手解答

背包实现未正确填充。已经尝试调试好几天了。仍然在学习

多校寒训TaoTao要吃鸡dp(未完成)

关于背包问题的一点小发现