唯一可以丟棄的數字是大於目標數字的數字,因爲任何其他小數字的組合可能總計達到期望的數量。
要找到哪些(如果有的話),你將不得不檢查剩餘數字的所有可能的組合。
最簡單的方法是遞歸遍歷列表,一旦添加了當前數字,並且一旦將其刪除,修剪當前分支(如果總和已經超過目標值)。
一個例子(perl的)實現您的問題例如在下面的代碼片段給出:
my @numbers = (4, 5, 10, 10, 23, 67, 889, 150, 50);
my $length = scalar @numbers; # length of the list
sub visit {
my ($i, $sum, $goal, $items) = @_;
# i: current index, sum: sum of numbers currently selected
# goal: goal value to reach, items: list of numbers currently selected
# we found a solution !
print join (", ", @$items) . "\n" if $sum == $goal;
return if $i >= $length || $sum >= $goal;
# continue without adding
visit ($i+1, $sum, $goal, $items);
# continue with adding
visit ($i+1, $sum + $numbers[$i], $goal, [$numbers[$i], @$items]);
}
visit (0, 0, 200, []);
它將報告對50, 150
預期。
注意,沒有試圖刪除重複製成,具有77 visit (0, 0, 77, []);
的目標值除了三重50, 23, 4
對67, 10
會列出兩次因此調用,因爲也有10
那兒兩個實例。
哦,不要相信任何在其他帖子中提出的貪婪算法,因爲它們註定會失敗解決揹包問題。
我不認爲你可以在達到總數後丟棄數字:如果它們沒有組合工作會怎麼樣?我認爲你必須繼續保持所有數字低於所需總數,並且可能從最高到最低。 – Rup
這個問題有一個非常有名的動態規劃算法。它被稱爲子集總和。 – Gene
你想計算總和等於'X'的子集的數量還是要查找是否有一個子集的'X'? – Karthik