[php]0-1背包动态规划

0-1背包是经典问题,有必要常常复习。

<?php
header("content-type:text/html;charset=utf-8");
$weight = array(2, 3, 44, 5, 15, 12);
$price = array(5, 5, 8, 17, 3, 7);
$limitw = 30;
echo "<pre/><br/>";
echo "物品重量<br/>".print_r($weight,1)."<br/>";
echo "对应价格<br/>".print_r($price,1)."<br/>";
echo "限制重量:".$limitw."<br/>========================================<br/>";
echo "不可重复放置同一物品的结果:<br/>";
print_r(bag01_dp($limitw,$weight,$price,false));
echo "可重复放置同一物品的结果:<br/>";
print_r(bag01_dp($limitw,$weight,$price,true));
/**
*@params
*$limitw -- 限重
*$weight -- 重量
*$price -- 价格
*$multiple -- true为可重复放置同一件物品,false表示每件物品只能放一次
*/
function bag01_dp($limitw,$weight,$price,$multiple)
{
$ps = $tp = array();
for($i = 0 ; $i <= $limitw ; $i++) :
foreach( $weight as $k=>$v) :
$o = $i -$v;
$li= $k-1;
$l = $weight[$li];
$lp = !$multiple ? $ps[$o][$l.$li] : max($ps[$o][$l.$li],$ps[$o][$v.$k]);
$lk = ($lp === $ps[$o][$l.$li]) ? $l.$li : $v.$k;
//当前物品重量 <= 当前背包最大承受重量
if( $v <= $i) :
//当前价格 + 剩余价格最优解 > 上次最优解
if( $price[$k] + $lp > $ps[$i][$l.$li]) :
$ps[$i][$v.$k] = $price[$k] + $lp;
$tp[$i][$v.$k] = $tp[$o][$lk];
$tp[$i][$v.$k][] = $v."(".$price[$k].")";
else :
$ps[$i][$v.$k] = $ps[$i][$l.$li];
$tp[$i][$v.$k] = $tp[$i][$lk];
endif;
else :
$ps[$i][$v.$k] = $ps[$i][$l.$li];
$tp[$i][$v.$k] = $tp[$i][$lk];
endif;
endforeach;
endfor;
return array('price'=>end(end($ps)),'items'=>end(end($tp)));
}

?>

结果:

---------------------------------------------------------------------------------------------------------------------------------------

物品重量
Array ( [0] => 2 [1] => 3 [2] => 44 [3] => 5 [4] => 15 [5] => 12 )
对应价格
Array ( [0] => 5 [1] => 5 [2] => 8 [3] => 17 [4] => 3 [5] => 7 )
限制重量:30
========================================
不可重复放置同一物品的结果:
Array ( [price] => 34 [items] => Array ( [0] => 2(5) [1] => 3(5) [2] => 5(17) [3] => 12(7) ) ) 可重复放置同一物品的结果:
Array ( [price] => 102 [items] => Array ( [0] => 5(17) [1] => 5(17) [2] => 5(17) [3] => 5(17) [4] => 5(17) [5] => 5(17) ) )
posted @ 2011-03-11 19:54  一缕青烟  阅读(526)  评论(0编辑  收藏  举报