c#预定义值是否可以加总为某个值

c#预定义值是否可以加总为某个值,c#,math,C#,Math,我有一个预定义int值的列表 List<int> values = new List<int>() { 1, 5, 7, 12, 20 }; 如何解决此问题?您必须从列表中获取所有组合,然后检查总和是否等于提供的值: 创建扩展方法以从值列表中获取组合(这将在稍后帮助您) 你的尝试在哪里?这些值可以重复使用还是只能重复使用一次?你能提供你所期望的输入/输出样本吗?@brijber否,如果这些值不包含1这听起来像是一系列与硬币/兑换相关的数学问题;基本上,您必须实现一个算法

我有一个预定义int值的列表

List<int> values = new List<int>() { 1, 5, 7, 12, 20 };

如何解决此问题?

您必须从列表中获取所有组合,然后检查总和是否等于提供的值:

创建扩展方法以从值列表中获取组合(这将在稍后帮助您)


你的尝试在哪里?这些值可以重复使用还是只能重复使用一次?你能提供你所期望的输入/输出样本吗?@brijber否,如果这些值不包含
1
这听起来像是一系列与硬币/兑换相关的数学问题;基本上,您必须实现一个算法并进行尝试。在
n
候选的最坏情况下,对
n
位进行二进制穷举扫描就足够了,而且非常容易实现(这只是
循环和位掩码的
),因此:如果
n
很小,这将是一个便宜的选择。随着
n
的增加,您需要更好的选择。当然,你可以先做一个完整的计算,看看是否可能。
public bool canBeSummed(int value)
{
//Can any of the values in values sum up to value?
}
public static class ExttensionMethods
{
    public static IEnumerable<IEnumerable<T>> Combinations<T>(this IEnumerable<T> elements, int k)
    {
        return k == 0 ? new[] { new T[0] } :
            elements.SelectMany((e, i) =>
            elements.Skip(i + 1).Combinations(k - 1).Select(c => (new[] { e }).Concat(c)));
    }
}
public bool CanBeSummed(int value, int[] values)
{
    if (values.Contains(value)) return true;
    var smaller = values.Where(x => x <= value);
    if (!smaller.Any()) return false; // all values are bigger than value
    var count = smaller.Count();
    if (count == 1) return false; // Only 1 number and it is not value since values.Contains(value) has to be false
    // Check all combinations from items (from 2 to x items where x is number of items in smaller list
    return Enumerable.Range(2, count - 1).Any(x => smaller.Combinations(x).Any(c => c.Sum() == value));
}
public static object[] SumTest =
{
    new object[] {6, true, new int[] {1, 5, 7, 12, 20}},
    new object[] {37, true, new int[] {1, 5, 7, 12, 20}},
    new object[] {9, false, new int[] {1, 5, 7, 12, 20}}
};

[TestCaseSource("SumTest")]
public void Test(int value, bool expectedResult, int[] values)
{
    Assert.AreEqual(expectedResult, CanBeSummed(value, values));
}