Length = input Long(can be 2550, 2880, 2568, etc)
List<long> = {618, 350, 308, 300, 250, 232, 200, 128}
該方案需要很長的值,我們必須找到從其中當添加給我一個輸入結果(相同的值,可以使用兩次)以上列表中的可能的組合,特別是長值。可以有+/- 30的差異。組合算法
最大的數字必須用得最多。
例:長度= 868 對於這種組合可以是
組合1 = 618 + 250
組合2 = 308 + 232 + 200 128
正確組合將是組合1
但也應該有不同的組合。
public static void Main(string[] args)
{
//subtotal list
List<int> totals = new List<int>(new int[] { 618, 350, 308, 300, 250, 232, 200, 128 });
// get matches
List<int[]> results = KnapSack.MatchTotal(2682, totals);
// print results
foreach (var result in results)
{
Console.WriteLine(string.Join(",", result));
}
Console.WriteLine("Done.");
}
internal static List<int[]> MatchTotal(int theTotal, List<int> subTotals)
{
List<int[]> results = new List<int[]>();
while (subTotals.Contains(theTotal))
{
results.Add(new int[1] { theTotal });
subTotals.Remove(theTotal);
}
if (subTotals.Count == 0)
return results;
subTotals.Sort();
double mostNegativeNumber = subTotals[0];
if (mostNegativeNumber > 0)
mostNegativeNumber = 0;
if (mostNegativeNumber == 0)
subTotals.RemoveAll(d => d > theTotal);
for (int choose = 0; choose <= subTotals.Count; choose++)
{
IEnumerable<IEnumerable<int>> combos = Combination.Combinations(subTotals.AsEnumerable(), choose);
results.AddRange(from combo in combos where combo.Sum() == theTotal select combo.ToArray());
}
return results;
}
public static class Combination
{
public static IEnumerable<IEnumerable<T>> Combinations<T>(this IEnumerable<T> elements, int choose)
{
return choose == 0 ?
new[] { new T[0] } :
elements.SelectMany((element, i) =>
elements.Skip(i + 1).Combinations(choose - 1).Select(combo => (new[] { element }).Concat(combo)));
}
}
我已經使用了上面的代碼,它可以更簡化,再次在這裏我也得到了獨特的價值。值可以被使用任意次數。但是,最大的數量必須得到最優先考慮。
我有一個驗證,以檢查總和是否大於輸入值。即使在那裏,邏輯也會失敗。
你的思想工作。是這樣嗎? –
是的列表是排序的。組合中沒有限制。它可以是2/3/4或更多。 – Santosh