组合算法实现
那天看到公司招聘应届生的笔试题,我发现其中有一道题,如果现场要我来写,我也不能搞定。
题目如下:从n个硬币中,找出等于面值相加等于s的最小硬币数组合。
思考了一下,这大概是个背包问题,解题的关键是如何遍历所有硬币组合,然后找出最优解。
该题的最优解就是 【最小组合】,所以我们从一个硬币找起,然后2 个硬币,3个硬币。。。
for(int i=1;i<=n;i++) { //找出所有 i 个硬币的组合。 //如果面值加起来等于 S 则说明找到最优解 }
那么,如何找出所有 i 个硬币的组合?
就是求Cni 嘛!
那怎么求排列组合呢?
以前在学校期间,由于学校水平不高,老师都跳过这一算法章节。嘿嘿,因为讲了没人听的懂。
所以排列组合的算法我不会,现在参加工作了,不能比不过刚毕业的学生吧。
如题:
用程序实现,找出从n个不同元素中,任取m(m≤n)个元素所有的组合。
解题需要用到下面的数学递推公式:
c(n,m)=c(n-1,m-1)+c(n-1,m)
从n个元素中选取m个元素,可以拆分成:先选取最后一个元素n,再从n-1 个元素中选取m-1 个元素,然后加上从排除n的 n-1 个元素中选取m元素。
递归实现代码:
1 public static void GetCombination(int source, int num, ref List<string> result, int[] temp = null) 2 { 3 if (temp == null) 4 { 5 temp = new int[num]; 6 } 7 if (source >= num && num >= 1) 8 { 9 temp[num - 1] = source; 10 11 if (num == 1) 12 { 13 result.Add(string.Join(",", temp)); 14 } 15 16 GetCombination(source - 1, num - 1, ref result, temp); 17 18 if (source > num) 19 { 20 GetCombination(source - 1, num, ref result, temp); 21 } 22 23 } 24 }
1 public static void GetCombination2(int source, int num, ref List<string> result, int[] temp = null) 2 { 3 if (temp == null) 4 { 5 temp = new int[num]; 6 } 7 for (int i = source; i >= num; i--) 8 { 9 temp[num - 1] = i; 10 if (num > 1) 11 { 12 GetCombination2(i - 1, num - 1, ref result, temp); 13 } 14 else 15 { 16 result.Add(string.Join(",", temp)); 17 } 18 } 19 }
1 List<string> result = new List<string>(); 2 GetCombination2(5, 3, ref result); 3 foreach (var a in result) 4 { 5 Console.WriteLine(a); 6 }
回到开头的那个题。把组合方法代进去就只可以了。
作者:张日海