Это большая проблема для размышления.Вдобавок ко всему, это псевдокод, который я бы использовал:
- A = массив элементов.
- A '= отсортированный массив элементов.
- S = сумма всех элементов.
- Пока A 'не пусто:
- V = целая часть S.
- R = остаток S = S - этаж(S)
- Сделать временную копию A ', X.
- Итерировать от наибольшего к наименьшему значению X как X [i]:
- Если X [i]
- Если R == 0, мы нашли решение.V - целое число, X содержит дополнения.STOP.
- Если X пусто, решения не существует.STOP.
- Уменьшить S на наибольшее значение в A '.S = S - Макс (A ').Удалите Макс (A ') из A'.
- Вернитесь к шагу № 4.
Конечно, я должен был посмотреть, сработает ли это на самом деле,Вот код (очень грязный, выбрасываемый), который я написал, чтобы проверить его:
<?php
$AA = $A = array(0.1, 0.2, 0.9, 0.5);
bcscale(8);
sort($AA, SORT_NUMERIC);
echo 'A = ' . implode(', ', $A), PHP_EOL;
echo 'A\' = ' . implode(', ', $AA), PHP_EOL;
$S = array_sum($AA);
echo 'S = ' . $S, PHP_EOL;
while (count($AA)) {
$V = floor($S);
echo 'V = ' . $V, PHP_EOL;
$R = bcsub($S, $V);
echo 'R = ' . $R, PHP_EOL;
$X = $AA;
$XX = array();
// Look for the largest value that is less than or equal to R.
for ($i = count($X) - 1; $i >= 0; $i--) {
echo 'X[i] = ' . $X[$i] . ', R = ' . $R, PHP_EOL;
$c = bccomp($X[$i], $R);
if ($c > 0) {
continue;
}
$XX[] = $X[$i];
$R = bcsub($R, $X[$i]);
unset($X[$i]);
if (bccomp($R, '0', strlen($R)) == 0) {
echo 'Largest whole number sum: ' . $V, PHP_EOL;
echo 'Elements: ' . implode(', ', $X), PHP_EOL;
break 2;
}
}
if (count($X) == 0) {
echo 'No sums to a whole number are possible.', PHP_EOL;
break;
}
$t = array_pop($AA);
$S = bcsub($S, $t);
}
echo 'S = ' . $S, PHP_EOL;
?>
Это уродливый алгоритм O (N ^ 2), но он должен быть правильным.Может кто-нибудь увидеть начальный начальный массив, где это не получится?
Ради интереса, я попробовал с массивом из 50 элементов, заменив первую строку на следующие строки:
$A = array();
for ($i = 0; $i < 50; $i++) {
$A[] = mt_rand(1, 99) / 100.0;
}
$AA = $A;
Краткий обзор, это выглядит правильно - я оставлю проверку кому-то еще;)