То, что вы описываете, является вариантом проблемы Рюкзак . Это вычислительно трудно решить эффективно, но для такого маленького набора это возможно.
Точная комбинация чисел для этого конкретного ввода:
29,318.07 + 5,881.05 + 3,174.40 + 3,085.00 + 2,231.25 + 1,320.00 + 1,000.00 + 125.00
Я использовал следующий Perl-скрипт для определения этого решения:
sub knapsack {
my ($target, $path, @vals) = @_;
if ($target == 0) {
print "Got it: @$path\n";
exit;
}
while (my $val = pop @vals) {
next if $val > $target;
knapsack($target - $val, [@$path, $val], @vals);
}
}
knapsack(46134_77, [], (
125_00, 1000_00, 1039_36, 1171_60, 1200_00, 1320_00, 1680_00, 1757_20,
1768_80, 1970_00, 2231_25, 2300_00, 2369_25, 2589_20, 2720_00, 2887_50,
3000_00, 3085_00, 3142_60, 3174_40, 3742_70, 3847_20, 5609_25, 5881_05,
12240_48, 14112_00, 29318_07, 32551_80,
));
Обратите внимание, что я преобразовал ваши десятичные значения в целые числа (умножив их все на 100), поскольку сравнения с плавающей точкой являются минным полем. (Подробнее см. Что должен знать каждый компьютерщик об арифметике с плавающей точкой .)