01背包
01背包(ZeroOnePack): 有N种物品和一个容量为V的背包。(每种物品均只有一件)第i个物品的重量是c[i],价值是w[i]。求解将哪些物品装入背包可使价值总和最大。这种背包问题的特点是:每种物品仅有一件,可以选择放或不放。 基于以上描述,定义我们的子问题:f[v]表示种子用户i分流给请求某种多媒体流用户数x的最小化能耗(最大化能耗分之一)。蜂窝网可看做单位能耗最大的一个种子用户。前i个种子用户满足请求某种多媒体流人数为x时可以获得的最小能耗(最大能耗倒数)。则其状态转移方程便是:f[v]=max{f[v],f[v-Ei]+w}。 把这个过程理解下:在种子用户i参不参加某种多媒体流的分流时有两种情况: 第一种是种子用户i参加,这时所得价值为:f[i-1][v]; 第二种是种子用户i不参加,这时所得价值为:f[i-1][v-c[i]]+w[i]; 最后比较第一种与第二种所得能耗的大小,哪种相对大,f[v]的值就是哪种。
算法:基于01背包的求解方法zoBag |
输入值:问题输入值 输出值:y,di 1.For i:1 to N For v:x to 0 //x为背包容量,v表示容量变化 F[i][v]=max{f[i-1][v],f[i-1][v-ei]+w}; End End
|
对于每一个种子用户i,我们都有参不参加分流两种选择。
序号 | 重量 | 价值 容量 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
1 | 4 | 6 | 0 | 6 | 6 | 6 | 6 | 6 | 6 | 6(1) |
2 | 5 | 4 | 0 | 6 | 6 | 6 | 6 | 6 | 10 | 10(1,2) |
3 | 6 | 5 | 0 | 6 | 6 | 6 | 6 | 6 | 10 | 11(1,3) |
4 | 2 | 3 | 3 | 6 | 6 | 9 | 9 | 9(1,4) | 10 | 11(1,3) |
5 | 2 | 6 | 6 | 9 | 9 | 12 | 12(1,5) | 15 | 15 | 15(1,4,5) |
这个最大价值是怎么得来的呢?
按行看:
第一行:只有1号物品,容量为10时,最大价值是6;
第二行:1,2可选,容量为10时选1,2,最大价值为10;
容量为9时选1,2,最大价值为10;
容量为8时选1,最大价值为6;…
第三行:1,2,3可选,容量为10时选1,3,最大价值为11;
容量为9时选1,2,最大价值为10;…
从以上最大价值的构造过程中可以看出。f[v]=max{f[v],f[v-ei]+w}这就是书本上写的动态规划方程。