1. 问题

有N件物品和一个容量为V的背包。放入第i件物品耗费的空间是C,得到的价值是W。求解装入背包的物品的价值总和最大是多少。(每种物品仅有一件,可选择放与不放)

2. 分析

这是一维动态规划问题,也叫背包问题。
公式:

  1. # f(i, v)表示前i件物品中选择若干放入一个容量为v的背包可获得的最大价值。
  2. f(i, v) = max(f(i-1), v), f(i-1, v-c[i] + w[i])

时间复杂度: O(V * N)
空间复杂度: O(V * N)

降维:

  1. dp[v] = max(dp[v], dp[v-c[i]] = w[i])

时间复杂度: O(V * N)
空间复杂度: O(V)

3. 解决

代码:

  1. <?php
  2. $thing = [
  3. ['c' => 9, 'w' => 10],
  4. ['c' => 4, 'w' => 5],
  5. ['c' => 6, 'w' => 4],
  6. ['c' => 7, 'w' => 9],
  7. ];
  8. $package = [];
  9. $cacheThing = [];
  10. function package($space) {
  11. // echo $space."\t";
  12. global $thing, $package, $cacheThing;
  13. if (isset($package[$space])) return $package[$space];
  14. $maxMoney = 0;
  15. foreach ($thing as $item) {
  16. if (($reSpace = $space - $item['c']) <= 0) continue;
  17. if (($w = package($reSpace) + $item['w']) <= $maxMoney) continue;
  18. $package[$space] = $maxMoney = $w;
  19. // print_r($package);
  20. $cacheThing[$space] = $item['w'];
  21. }
  22. return $maxMoney;
  23. }
  24. echo package(20);
  25. print_r($package);
  26. print_r($cacheThing);