0-1背包

Posted messi2017

tags:

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

接下来看一个动态规划的经典问题:0-1背包问题  

问题描述:

   给定n种物品和一背包。物品i的重量是wi,其价值为vi,背包的容量为C。问应如何选择装入背包的物品,使得装入背包中物品的总价值最大?
这个问题确实是要困难一些,首先这个状态就不是很好确定,由于个额外的条件,背包容量有限,所以要兼顾考虑两个因素的限制,一个是选什么物品,一个是总重量不过界。为此我们采用二维数组,利用两个维度的索引值来解决这个问题。
假设代表重量的数组为W,代表价值的数组为P。
状态c[ i ][ j ]表示前 i 件物品在重量 j 内的最大总价值,注意这个状态不是很好理解,前 i 件物品可以选可以不选,重量 j 内说明当前状态的总重量并没有超过 j。
同样这个问题的状态转移方程也不是很好理解,对于c[ i ][ j ],当 j < W【i】时,这个物件装不下,此时c[ i ][ j ]  = c[ i - 1 ][ j ]
当 j > W【i】时,这个物品能够装下,但是此时有两种情况,第一种仍然是c[ i - 1 ][ j ](可以理解为不装这个物品),第二种情况是c[ i - 1 ][ j - W[ i ] ] + p[ i ](装下这个物品,但是会涉及到前一个状态c[ i - 1 ][ j - W[ i ] ],这个我暂时没办法讲的很清楚,不过这个表达式的确是这样的),此时c[ i ][ j ] 为两者中较大的那个值。
直接上代码,我直接定义了一种情况:
 1 void main(){
 2 
 3 int weight = 120;
 4     int w[6] = {0,40,50,70,40,20};   
 5     int p[6] = {0,10,25,40,20,10};
 6     int **c = (int**)malloc((6)*sizeof(int*));
 7     for (int i = 0; i <= 5; ++i){
 8         c[i] = (int*)malloc((weight+1)*sizeof(int));
 9     }
10     int temp1 = 0;
11     int temp2 = 0;
12     for (int i = 0; i <= weight; ++i)
13         c[0][i] = 0;
14     for (int i = 1; i <= 5; ++i){
15         c[i][0] = 0;
16         for (int j = 1; j <= weight; ++j){
17             if (w[i] > j)c[i][j] = c[i - 1][j];
18             else{
19                 temp1 = c[i - 1][j];
20                 temp2 = c[i - 1][j - w[i]] + p[i];
21                 c[i][j] = temp1 > temp2 ? temp1 : temp2;
22             }
23         }
24     }
25         
26     cout << c[5][120] << endl;
27 }

 

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

背包0-1背包与完全背包一维数组实现

0-1背包问题

0-1背包问题

0-1背包问题

0-1背包问题的回溯法中,剪枝用的上界函数问题

0/1背包