題目:給定的一組整數,給定一個值X,找出和為X的任意組合。
思路:將X視為重量x(kg)的物品,放在天平左側,數組中的每個數字視為重量為y(kg)的砝碼,砝碼從大到小逐一放置,直到天平平衡,那么選擇的砝碼的組合就是我們所要的答案。采用遞歸的方法。
- 右側還有x的余量
- 放置第一個砝碼后還有x-y1的余量
- 放置第二個砝碼后還有(x-y1)-y2的余量
- 以此類推

static void Main(string[] args) { NumberGame.Execute(); Console.ReadKey(); } public static class NumberGame { private static int[] arr = { 1, 8, 3, 6, 5, 2, 9, 7, 4 }; private const int TOTAL = 11; //指定合計數 private static int groupNum = 0; class NumberType { public int Number { get; set; } public bool Used { get; set; } } public static void Execute() { Console.WriteLine($"數組[{string.Join(",", arr)}]中任意一組數和為{TOTAL}的所有組合:"); List<NumberType> list = arr.OrderBy(x => x).Select(x => new NumberType { Number = x, Used = false }).ToList(); FindNums(list, TOTAL, list.Count - 1); } /// <summary> /// 利用遞歸方法找出所有組合 算法:TOTAL按數組倒序逐一減,如有余數remainder>=0則繼續遞歸 /// </summary> /// <param name="list">從小到大排序的數組</param> /// <param name="remainder">剩余數</param> /// <param name="loop">本次循環次數</param> private static void FindNums(List<NumberType> list, int remainder, int loop) { if (remainder == 0)//找到一組 { Console.WriteLine($"第{++groupNum}組:{string.Join(" + ", list.Where(x => x.Used).Select(x => x.Number).ToArray())}"); return; } for (int i = loop; i >= 0; i--) { if (!list[i].Used && (remainder - list[i].Number) >= 0) { list[i].Used = true; FindNums(list, remainder - list[i].Number, i - 1); list[i].Used = false; } } } }

