01背包,完全背包
2017-09-03 10:58
323 查看
01,完全,多重背包模版:
http://blog.csdn.net/u012860063/article/details/32911251
01背包:
转载自:
http://blog.csdn.net/qq_34374664/article/details/52230368
https://www.cnblogs.com/Kalix/p/7622102.html
https://www.cnblogs.com/Kalix/p/7622102.html
先看问题:
有N件物品和一个容量为V的背包。(每种物品均只有一件)第i件物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使价值总和最大。
通过阅读问题,因为背包就是要往里面放东西,所以一件物品就是有放或不放两种情况,那么怎么才能判断当前物品该不该放进去从而使利益最大化呢。
首先,我们用i代表前i件物品,v代表包的最大承重,ci是第i件物品的重量、wi是第i件物品的价值、f[i,j]是最大价值(i个物品放入有j个空间的包)。
第一种情况:第i件不放进去,这时所得价值(f[i][j])为:f[i][j]=f[i-1][v]
因为不放进去,所以说当前价值(f[i][j])为前i-1个物品的价值f[i-1][v]:当前i个物品用j个空间所拥有的价值就等于前i-1个物品用j个空间的价值,因为物品i没有放进去,
所以就相当于继承f[i-1][v]了,所以f[i][j]=f[i-1][v]
另一种情况:第i件放进去,这时所得价值为:f[i][j]=f[i-1][v-c[i]]+w[i]
因为放进去了,所以说当前价值(f[i][j])不是前i-1个物品的价值f[i-1][v]:因为你放进去了,所以这个时候包内的空间就不是v了,而应该是v-c[i],所以说,
你现在需要继承前i-1个物品占用体积为v-c[i]时的价值,因为你将物品放进去了,所以还需要加上当前物品价值wi,所以f[i][j]=f[i-1][v-c[i]]+w[i]
因为对于第i件物品就是这两种操作,而你又想要最大价值,所以
f[i][j]=max(f[i-1][v],f[i-1][v-c[i]]+w[i])
贴一段代码:(n为物品数量)
我们再进行优化,改变一下dp思路,让f[i][j]表示出在前i种物品中选取若干件物品放入容量为j的背包所得的最大价值。
所以说,对于第i件物品有放或不放两种情况,而放的情况里又分为放1件、2件、……v/c[i]件
如果不放那么f[i][j]=f[i-1][j];如果确定放,那么当前背包中应该出现至少一件第i种物品,所以f[i][j]中至少应该出现一件第i种物品,即f[i][j]=f[i][j-c[i]]+w[i],为什么会是f[i][j-c[i]]+w[i]?
因为我们要把当前物品i放入包内,因为物品i可以无限使用,所以要用f[i][j-c[i]];如果我们用的是f[i-1][j-c[i]],f[i-1][j-c[i]]的意思是说,我们只有一件当前物品i,所以我们在放入物品i的时候需要考虑到第i-1个物品
4000
的价值(f[i-1][j-c[i]]);但是现在我们有无限件当前物品i,我们不用再考虑第i-1个物品了,我们所要考虑的是在当前容量下是否再装入一个物品i,而[j-c[i]]的意思是指要确保f[i][j]至少有一件第i件物品,所以要预留c[i]的空间来存放一件第i种物品。总而言之,如果放当前物品i的话,它的状态就是它自己”i”,而不是上一个”i-1”。
所以说状态转移方程为:
f[i][j]=max(f[i-1][j],f[i][j-c[i]]+w[i])
贴一段代码:
完全背包:
先看问题:在n种物品中选取若干件(同一种物品可多次选取)放在空间为v的背包里,每种物品的体积为c1,c2,…,cn,与之相对应的价值为w1,w2,…,wn.求解怎么装物品可使背包里物品总价值最大
看完这个问题,你也许会觉得这个不就是01背包的升级版吗,其实就是这样,完全背包问题与01背包问题的区别在于完全背包每一件物品的数量都有无限个,而01背包每件物品数量只有1个
所以说与它相关的策略已经不是只有取和不取这两种策略了,而是有取0件、取1件、取2件……等等很多种策略
如果我们用和01背包一样的状态,f[i][v]表示前i种物品恰放入一个容量为v的背包的最大价值,那我们应该用k表示当前容量下可以装第i种物品的件数,那么k的范围应该是0≤k≤v/c[i],
既然要用当前物品i把当前容量装满,那需要0≤k≤v/c[i]件,其中k表示件数。
下面给出状态转移方程:
f[i][j] = max{f[i-1][v],f[i-1][v - k * c[i]] + k * w[i]}(0<=k*c[i]<=v)
我们再进行优化,改变一下dp思路,让f[i][j]表示出在前i种物品中选取若干件物品放入容量为j的背包所得的最大价值。
所以说,对于第i件物品有放或不放两种情况,而放的情况里又分为放1件、2件、……v/c[i]件
如果不放那么f[i][j]=f[i-1][j];如果确定放,那么当前背包中应该出现至少一件第i种物品,所以f[i][j]中至少应该出现一件第i种物品,即f[i][j]=f[i][j-c[i]]+w[i],为什么会是f[i][j-c[i]]+w[i]?
因为我们要把当前物品i放入包内,因为物品i可以无限使用,所以要用f[i][j-c[i]];如果我们用的是f[i-1][j-c[i]],f[i-1][j-c[i]]的意思是说,我们只有一件当前物品i,所以我们在放入物品i的时候需要考虑到第i-1个物品的价值(f[i-1][j-c[i]]);但是现在我们有无限件当前物品i,我们不用再考虑第i-1个物品了,我们所要考虑的是在当前容量下是否再装入一个物品i,而[j-c[i]]的意思是指要确保f[i][j]至少有一件第i件物品,所以要预留c[i]的空间来存放一件第i种物品。总而言之,如果放当前物品i的话,它的状态就是它自己”i”,而不是上一个”i-1”。
所以说状态转移方程为:
f[i][j]=max(f[i-1][j],f[i][j-c[i]]+w[i])
http://blog.csdn.net/u012860063/article/details/32911251
01背包:
转载自:
http://blog.csdn.net/qq_34374664/article/details/52230368
https://www.cnblogs.com/Kalix/p/7622102.html
https://www.cnblogs.com/Kalix/p/7622102.html
先看问题:
有N件物品和一个容量为V的背包。(每种物品均只有一件)第i件物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使价值总和最大。
通过阅读问题,因为背包就是要往里面放东西,所以一件物品就是有放或不放两种情况,那么怎么才能判断当前物品该不该放进去从而使利益最大化呢。
首先,我们用i代表前i件物品,v代表包的最大承重,ci是第i件物品的重量、wi是第i件物品的价值、f[i,j]是最大价值(i个物品放入有j个空间的包)。
第一种情况:第i件不放进去,这时所得价值(f[i][j])为:f[i][j]=f[i-1][v]
因为不放进去,所以说当前价值(f[i][j])为前i-1个物品的价值f[i-1][v]:当前i个物品用j个空间所拥有的价值就等于前i-1个物品用j个空间的价值,因为物品i没有放进去,
所以就相当于继承f[i-1][v]了,所以f[i][j]=f[i-1][v]
另一种情况:第i件放进去,这时所得价值为:f[i][j]=f[i-1][v-c[i]]+w[i]
因为放进去了,所以说当前价值(f[i][j])不是前i-1个物品的价值f[i-1][v]:因为你放进去了,所以这个时候包内的空间就不是v了,而应该是v-c[i],所以说,
你现在需要继承前i-1个物品占用体积为v-c[i]时的价值,因为你将物品放进去了,所以还需要加上当前物品价值wi,所以f[i][j]=f[i-1][v-c[i]]+w[i]
因为对于第i件物品就是这两种操作,而你又想要最大价值,所以
f[i][j]=max(f[i-1][v],f[i-1][v-c[i]]+w[i])
贴一段代码:(n为物品数量)
for (int i=1;i<=n;++i) { for (int j=v;j>=0;--j) { if(c[i]<=j)//如果当前物品可以放入当前空间的背包 f[i][j]=max(f[i-1][j],f[i-1][j-c[i]]+w[i]); else f[i][j]=f[i-1][j];//如果当前物品放不进去,那么继承前i个物品在当前空间大小时的价值 } }
我们再进行优化,改变一下dp思路,让f[i][j]表示出在前i种物品中选取若干件物品放入容量为j的背包所得的最大价值。
所以说,对于第i件物品有放或不放两种情况,而放的情况里又分为放1件、2件、……v/c[i]件
如果不放那么f[i][j]=f[i-1][j];如果确定放,那么当前背包中应该出现至少一件第i种物品,所以f[i][j]中至少应该出现一件第i种物品,即f[i][j]=f[i][j-c[i]]+w[i],为什么会是f[i][j-c[i]]+w[i]?
因为我们要把当前物品i放入包内,因为物品i可以无限使用,所以要用f[i][j-c[i]];如果我们用的是f[i-1][j-c[i]],f[i-1][j-c[i]]的意思是说,我们只有一件当前物品i,所以我们在放入物品i的时候需要考虑到第i-1个物品
4000
的价值(f[i-1][j-c[i]]);但是现在我们有无限件当前物品i,我们不用再考虑第i-1个物品了,我们所要考虑的是在当前容量下是否再装入一个物品i,而[j-c[i]]的意思是指要确保f[i][j]至少有一件第i件物品,所以要预留c[i]的空间来存放一件第i种物品。总而言之,如果放当前物品i的话,它的状态就是它自己”i”,而不是上一个”i-1”。
所以说状态转移方程为:
f[i][j]=max(f[i-1][j],f[i][j-c[i]]+w[i])
贴一段代码:
for (int i=1;i<=n;++i) { for (int j=v;j>=0;--j) { if(t[i]<=j) f[j]=max(f[j],f[j-c[i]]+c[i]); else f[j]=f[j]; } }
完全背包:
先看问题:在n种物品中选取若干件(同一种物品可多次选取)放在空间为v的背包里,每种物品的体积为c1,c2,…,cn,与之相对应的价值为w1,w2,…,wn.求解怎么装物品可使背包里物品总价值最大
看完这个问题,你也许会觉得这个不就是01背包的升级版吗,其实就是这样,完全背包问题与01背包问题的区别在于完全背包每一件物品的数量都有无限个,而01背包每件物品数量只有1个
所以说与它相关的策略已经不是只有取和不取这两种策略了,而是有取0件、取1件、取2件……等等很多种策略
如果我们用和01背包一样的状态,f[i][v]表示前i种物品恰放入一个容量为v的背包的最大价值,那我们应该用k表示当前容量下可以装第i种物品的件数,那么k的范围应该是0≤k≤v/c[i],
既然要用当前物品i把当前容量装满,那需要0≤k≤v/c[i]件,其中k表示件数。
下面给出状态转移方程:
f[i][j] = max{f[i-1][v],f[i-1][v - k * c[i]] + k * w[i]}(0<=k*c[i]<=v)
for (int i = 1; i < n; i++){ for (int j = 1; j <= v; j++){ for (int k = 0; k*c[i] <= j; k++){ if(c[i]<=j)/*如果能放下*/ f[i][j] = max{f[i-1][j],f[i-1][j - k * c[i]] + k * w[i]};/*要么不取,要么取0件、取1件、取2件……取k件*/ else/*放不下的话*/ f[i][j]=f[i-1][j]/*继承前i个物品在当前空间大小时的价值*/ } } }
我们再进行优化,改变一下dp思路,让f[i][j]表示出在前i种物品中选取若干件物品放入容量为j的背包所得的最大价值。
所以说,对于第i件物品有放或不放两种情况,而放的情况里又分为放1件、2件、……v/c[i]件
如果不放那么f[i][j]=f[i-1][j];如果确定放,那么当前背包中应该出现至少一件第i种物品,所以f[i][j]中至少应该出现一件第i种物品,即f[i][j]=f[i][j-c[i]]+w[i],为什么会是f[i][j-c[i]]+w[i]?
因为我们要把当前物品i放入包内,因为物品i可以无限使用,所以要用f[i][j-c[i]];如果我们用的是f[i-1][j-c[i]],f[i-1][j-c[i]]的意思是说,我们只有一件当前物品i,所以我们在放入物品i的时候需要考虑到第i-1个物品的价值(f[i-1][j-c[i]]);但是现在我们有无限件当前物品i,我们不用再考虑第i-1个物品了,我们所要考虑的是在当前容量下是否再装入一个物品i,而[j-c[i]]的意思是指要确保f[i][j]至少有一件第i件物品,所以要预留c[i]的空间来存放一件第i种物品。总而言之,如果放当前物品i的话,它的状态就是它自己”i”,而不是上一个”i-1”。
所以说状态转移方程为:
f[i][j]=max(f[i-1][j],f[i][j-c[i]]+w[i])
for(int i = 0 ; i < n ; i ++) { for(int j = 1 ; j <= v ; j++) { if(c[i]<=j) f[i][j] = max(f[i-1][j],f[i][j-c[i]]+w[i]); else f[i][j]=f[i-1][j]; } }
相关文章推荐
- 01背包、完全背包、多重背包模板
- 01背包、完全背包、多重背包
- 背包之01背包、完全背包、多重背包详解
- POJ 3628 Bookshelf2 / POJ 3624 Charm Bracelet / POJ 1384 初涉01背包与完全背包
- 01背包和完全背包
- 01背包问题和完全背包问题 (转载)
- 背包之01背包、完全背包、多重背包详解
- 01背包,完全背包
- 背包整理(1) 01,完全,多重
- 背包之01背包、完全背包、多重背包详解
- 背包问题中的01背包和完全背包
- 混合背包模板(01+多重+完全)
- 背包之01,完全,多重模板
- 背包问题【01、完全(恰好or不超过)、多重】【尚未整理完】
- 01背包,完全背包
- 四种背包问题(01和完全)
- 夕拾算法进阶篇:17)01背包和完全背包问题 (动态规划DP)
- 背包之01背包、完全背包、多重背包详解
- HDU 5410 CRB and His Birthday (01背包,完全背包,混合)
- 01背包、完全背包、多重背包归纳