我需要确定所有可能的钞票组合的给定输入。
int[] currency = new int[] { 5, 10, 20, 50, 100, 200, 500 };
int total = 20; // result is { {5,5,5,5} {5,5,10} {10,10} {20} }
int[][] result = GetCombinations(total, 0, currency); // should return the 4 combinations
这是我到目前为止所尝试的内容。
public static int GetCombinations(int total, int index, int[] list)
{
total = total - list[index];
if (total < 0)
{
return 0;
}
else if (total == 0)
{
return 1;
}
else
{
return 1 + GetCombinations(total, index + 1, list);
}
}
赏金问题:
我需要一种方法来获得所有组合 - 而不仅仅是计数。
答案 0 :(得分:3)
您只计算{5},{5,10}。
您正在计算&#34;如果成本&lt; = 20?&#34;,可以使用多少个不同的硬币。
所以,你必须指望这个算法。
正确的代码是:
public static int GetCombinations(int total, int index, int[] list)
{
if (total == 0)
{
return 1;
}
if(index == list.Length) {
return 0;
}
int ret = 0;
for(; total >= 0; total -= list[index])
{
ret += GetCombinations(total, index + 1, list);
}
return ret;
}
如果要计算组合数,还可以解决dp[total][index]
的动态编程和记忆,因为如果total和index相同,则GetCombinations(total, index, list)
值相同。
编辑:
如果你想要所有组合,你可以这样做:
using System;
using System.Collections.Generic;
class Program {
public static int GetCombinations(int total, int index, int[] list, List<int> cur) {
if (total == 0) {
foreach(var i in cur) {
Console.Write(i + " ");
}
Console.WriteLine();
return 1;
}
if(index == list.Length) {
return 0;
}
int ret = 0;
for(; total >= 0; total -= list[index]) {
ret += GetCombinations(total, index + 1, list, cur);
cur.Add(list[index]);
}
for(int i = 0; i < cur.Count; i++) {
while(cur.Count > i && cur[i] == list[index]) {
cur.RemoveAt(i);
}
}
return ret;
}
public static void Main() {
int[] l = { 5, 10, 20, 50, 100, 200, 500 };
GetCombinations(20, 0, l, new List<int>());
}
}
我改进了代码,现在您可以使用递归来枚举所有组合
在此代码中,它按字典顺序列举组合
我核实了sum=20, 75
个案例。