问题是这样的:
一家公司以一组包装尺寸提供小部件:
客户可以订购任意数量的小部件,但是以下规则适用:
一些示例显示订购的小部件数量以及正确完成订单所需的包装数量和尺寸:
我研究了一些算法(贪婪的硬币找零,LAFF等),因为它们似乎提供了类似的解决方案。但是,理想情况下,我正在寻找一种可扩展的,面向对象的方法来解决此问题。
这是到目前为止我要提出的:
<?php
function countWidgets($amount)
{
$packs = array(5000, 2000, 1000, 500,
250);
$packCounter = array(0, 0, 0, 0, 0);
$packsCount = count($packs);
// loop packs
for ($i = 0; $i < $packsCount; $i++)
{
if ($amount >= $packs[$i])
{
$packCounter[$i] = intval($amount /
$packs[$i]);
$amount = $amount -
$packCounter[$i] *
$packs[$i];
}
}
// if remainder
if ($amount > 0) {
// and if smallest pack size populated
if ($packCounter[4] == 1) {
// clear smallest pack size
$packCounter[4] = 0;
// increment next biggest pack size
$packCounter[3] += 1;
} else {
// increment smallest pack size
$packCounter[4] +=1;
}
}
// Print packs
echo ("Pack ->"."\n");
for ($i = 0; $i < $packsCount; $i++)
{
if ($packCounter[$i] != 0)
{
echo ($packs[$i] . " : " .
$packCounter[$i] . "\n");
}
}
}
$amount = 251;
countWidgets($amount);
答案 0 :(得分:0)
好的,我同意这比我昨天假设的要难一些。您基本上有两个相反的要求:
您不能同时满足这两个条件。因此,如果我尝试发送1200个小部件,规则2说我应该发送2000个数据包,但是规则1说我应该发送2个数据包:1000个和250个。应该以哪个规则为准?
我选择在以下解决方案中以规则1为准。原因是没有客户想要比绝对必要更多的小部件。
$packSizes = [ 250,
500,
1000,
2000,
5000];
function optimizePacks($packSizes,$number)
{
rsort($packSizes);
$requiredPacks = array_fill_keys($packSizes,0);
foreach ($packSizes as $size) {
$packs = floor($number/$size);
if ($packs > 0) {
$requiredPacks[$size] = $packs;
$number -= $packs*$size;
}
}
if ($number > 0) $requiredPacks[min($packSizes)]++;
return $requiredPacks;
}
$packs = optimizePacks($packSizes,6666);
print_r($packs);
这将适用于任何包装尺寸的阵列和任意数量的小部件。此代码的输出是:
数组( [5000] => 1 [2000] => 0 [1000] => 1 [500] => 1 [250] => 1)
哪一个包比规则2要求的多一包(5000个和1000个中的两个)。当然,可以让规则2占上风,但是我不能同时满足这两个规则。