编 写: zhangyue
时 间: 2016-12-27
说 明: 利用背包问题解决红包使用问题
一 01背包问题
01背包问题是指在一个容量大小固定为M的背包中,装入体积和价值不同的宝石,怎么选择才能在背包中得到最大的价值。
二 动态规划
动态规划是指 通过拆分问题,定义问题状态和状态之间的关系,使得问题能够以一种循环的方式去解决。 通常基于一个递推公式和一个或多个初始状态,当前子问题的解由上一个子问题的解推出。 有一类活动的过程,由于它的特殊性,可将过程分成若干个互相联系的阶段,在它的每一阶段都需要作出决策,从而使整个过程达到最 好的活动效果。当然,各个阶段决策的选取不是任意确定的,它依赖于当前面临的状态,又影响以后的发展,当各个阶段决策确定后,就组成一个决策序列,因而也就确定了整个过程的一条活动路线 状态转移方程: d(N,M) = max(d(N-1,M), d(N-1, M-weight(i)) + value(i)); d(N,M) 有容量为M的背包,有N个宝石 d(N-1,M) 当前的宝石不放入背包,所能获取的最大价值 d(N-1, M-weight(i)) + value(i) 当前宝石放入背包,所能够获取的最大价值
三 代码
function getResult($bagItems, $bagSize) { var result = array(); //生成状态数组 foreach ($i = 0; $i < $bagSize; $i ++) { foreach ($j = 0; $j < count($bagItems); $j ++) { if ($bagItems[$j]['weight'] > $i) { //当前重量大于当前背包总重量 if (j != 0) { $result[$j][$i] = $result[$j-1][$i]; } else { //第一个元素 $j-1不存在,不存在前一个状态 $result[$j][$i] = 0; } } else { //当前重量小于背包,可以放入背包 if ($j != 0 ) { $tmp_value = $result[$j-1][$i - $bagItems[$j]['weight']] + $bagItems[$j]['weight']; $result[$j][$i] = max($result[$j-1][$i], $tmp_value); } else { //第一个元素 $j-1不存在,不存在前一个状态 $result[$j][$i] = $bagItems[$j]['weight']; } } } } //根据得到的状态得到所选的数组 $return = array();//存储放回的组合 $cur_size = $bagSize;//当前红包容量 for ($n = count($bagItems); $n >= 0 ; $n--) { if ($cur_size == 0) { break; } if ($n == 0 && $bagItems[$n]['weight'] < $cur_size) { $return[] = $bagItems[$n]['id']; break; } if ($bagItems[$n][$cur_size] - $bagItems[$n-1][$cur_size - $bagItems[$n]['weight']] == $bagItems[$n]['weight']) { //判断当前的这个商品是不是在最优解里,如果不在则不放入 $return[] = $bagItems[$n]['id']; $cur_size = $cur_size - $bagItems[$n]['weight']; } } //得到结果 return $return; }
四 递推表格
函数得到的递推表格和最终最优结果:
体积 | 价值 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
4 | 4 | 0 | 0 | 0 | 0 | 4 | 4 | 4 | 4 | 4 | 4 | 4 | 4 |
5 | 5 | 0 | 0 | 0 | 0 | 4 | 5 | 5 | 5 | 5 | 9 | 9 | 9 |
6 | 6 | 0 | 0 | 0 | 0 | 4 | 5 | 6 | 6 | 6 | 9 | 10 | 11 |
五 红包问题
使用红包时,只需要将价值和体积都类比于红包的金额即可,这样可以选出最后得到的红包使用组合。 存在问题: 1 红包会涉及小数的问题,红包现在只保留两位小数,最简单的方法是给红包*100,这样会增加递推数组的大小,增加空间复杂度 2 红包还存在过期时间,可考虑如何加上过期时间这一条件 3 由于红包价格和体积是同一个值,可考虑简化算法