计算给定面值集的值的最佳方法

时间:2013-08-29 14:25:19

标签: php

因此,例如,在给定1,2,5,10,20,50的面额集合的情况下得到值237,构成该值的最佳方式是4x50 + 1x20 + 1x10 + 1x5 + 1x2。但是如何在PHP中以编程方式实现呢?

1 个答案:

答案 0 :(得分:1)

你可以这样做:

$number = 237;

$values = array(1, 2, 5, 10, 20, 50);
arsort($values); // greater to lower sorting
$numberOf = array();

foreach ($values as $v) {
    $numberOf[$v] = floor($number / $v);
    $number -= $numberOf[$v] * $v;
}

var_dump($numberOf);

这将产生:

array(6) {
  [50]=>
  int(4)
  [20]=>
  int(1)
  [10]=>
  int(1)
  [5]=>
  int(1)
  [2]=>
  int(1)
  [1]=>
  int(0)
}

<强> the demo

编辑:有限金额的面额

如果您没有无限的面额,可以试试这个:

$number = 237;

$values = array(1, 2, 5, 10, 20, 50);
$quantities = array(7, 1, 3, 5, 2, 3);
// sort by greater value to lower value
// but keeping the related quantities
array_multisort($values, SORT_DESC, $quantities);

$numberOf = array();

foreach ($values as $i => $v) {
    $quantity = $quantities[$i]; // get the corresponding quantity
    // if we have less than the required value, we put the max we can
    $numberOf[$v] = floor($number / $v) > $quantity ? $quantity : floor($number / $v);
    $number -= $numberOf[$v] * $v;
}

var_dump($numberOf);

在此示例中,3的数量仅为50。所以你会有一个输出:

array(6) {
  [50]=>
  int(3)
  [20]=>
  int(2)
  [10]=>
  float(4)
  [5]=>
  float(1)
  [2]=>
  float(1)
  [1]=>
  float(0)
}
  

3 * 50 + 2 * 20 + 4 * 10 + 5 * 1 + 2 * 1 + 1 * 0 = 237

Yippee!
The demo

另请参阅array_multisort()以了解此关键字:

array_multisort($values, SORT_DESC, $quantities);

更好的是,准备就绪的功能:

function getDenominations($amount, $denominations, $quantities = null) {
    if (is_array($quantities) && count($denominations) != count($quantities)) return false;
    array_multisort($denominations, SORT_DESC, $quantities);

    $numberOf = array();

    foreach ($denominations as $i => $v) {
        $quantity = $quantities[$i]; 
        $numberOf[$v] = floor($amount/ $v) > $quantity ? $quantity : floor($amount / $v);
        $amount -= $numberOf[$v] * $v;
    }

    return $amount == 0 ? $numberOf : false;
}

要像这样使用:

$result = getDenominations(
    237,
    array(1, 2, 5, 10, 20, 50),
    array(7, 1, 3, 5, 0, 4)
);

var_dump($result);

返回值:array | bool

如果未指定数量,则返回无限金额的面额。如果指定,则数量有限 返回&#34; false&#34;是否数量不足或阵列的大小是否不同。