这类问题可能已经得到了解答,但我不能超越我想用C#编写的小程序的构思过程。
我想做的是:
- 我有n = 100
- 我还有9个变量/ 9个数组
- 我希望获得在所有9个变量之间分配n的所有可能组合,例如:
v1 = 100;
v2 = 0;
v3 = 0;
v4 = 0;
v5 = 0;
v6 = 0;
v7 = 0;
v8 = 0;
v9 = 0;
或
v1 = 10;
v2 = 5;
v3 = 13;
v4 = 27;
v5 = 0;
v6 = 34;
v7 = 0;
v8 = 11;
v9 = 0;
我看过堆的algorythm,但它似乎不适合,或者我可能不理解完整的概念。
另外,计算组合数的方法是什么,产品方法是正确的吗?
编辑:我找到了使用在线工具找到延续的可能组合的数量。总数为“352 025 629 371”。是的,需要一段时间来完成所有这些。
答案 0 :(得分:0)
这可能会让你入门。它只是暴力强迫所有的组合。
using System;
using System.Collections.Generic;
using System.Linq;
namespace Bob
{
public class Program
{
private static IEnumerable<Combination> GetData()
{
for (int a = 0; a < 101; a++)
{
for (int b = 0; b < 101; b++)
{
for (int c = 0; c < 101; c++)
{
for (int d = 0; d < 101; d++)
{
for (int e = 0; e < 101; e++)
{
for (int f = 0; f < 101; f++)
{
for (int g = 0; g < 101; g++)
{
for (int h = 0; h < 101; h++)
{
for (int i = 0; i < 101; i++)
{
var sum = a + b + c + d + e + f + g + h + i;
if (sum == 100)
{
yield return new Combination(a, b, c, d, e, f, g, h, i);
}
else if (sum > 100)
{
break;
}
}
}
}
}
}
}
}
}
}
}
static void Main(string[] args)
{
var sampleResults = GetData().Take(200); // this will show 200 (remove .Take(100) to show them all)
foreach (var result in sampleResults)
{
Console.WriteLine(result);
}
Console.ReadLine();
}
}
public class Combination
{
public readonly int V1;
public readonly int V2;
public readonly int V3;
public readonly int V4;
public readonly int V5;
public readonly int V6;
public readonly int V7;
public readonly int V8;
public readonly int V9;
public Combination(int v1, int v2, int v3, int v4, int v5, int v6, int v7, int v8, int v9)
{
V1 = v1;
V2 = v2;
V3 = v3;
V4 = v4;
V5 = v5;
V6 = v6;
V7 = v7;
V8 = v8;
V9 = v9;
}
public override string ToString()
{
return string.Format("{0} {1} {2} {3} {4} {5} {6} {7} {8}", V1, V2, V3, V4, V5, V6, V7, V8, V9);
}
}
}
答案 1 :(得分:0)
mjwills解决方案的替代方法是使用暴力破解的递归方法。
优化是不会运行所有内容,而是将搜索限制为最多100个数字 - 当前总和(因为如果当前总和是50,我们知道下一个数字不可能是&gt;因为那将总和超过100。)。
public class Program
{
static void Main(string[] args)
{
var sampleResult2 = BruteForceCombinations(new List<int>(), new List<Combination>());
foreach (var result in sampleResult2)
{
Console.WriteLine(result);
}
Console.ReadLine();
}
private static IEnumerable<Combination> BruteForceCombinations(List<int> listSoFar = null, List<Combination> validCombinations = null)
{
if (listSoFar.Count == 9)
{
if (listSoFar.Sum() == 100)
{
List<int> validCombinationList = new List<int>();
validCombinationList.AddRange(listSoFar);
validCombinations.Add(new Combination(validCombinationList));
}
}
else
{
// Run from 0 to 100 - the sum of list entries so far + 1, as any number larger than that will create a sum larger than 100
for (int i = 0; i < 100 - listSoFar.Sum() + 1; i++)
{
// Add the number to test the combination and remove after
// The combination is added if we hit one that sums to 100.
listSoFar.Add(i);
BruteForceCombinations(listSoFar, validCombinations);
listSoFar.RemoveAt(listSoFar.Count-1);
}
}
return validCombinations;
}
}
public class Combination
{
private readonly List<int> numbers;
public Combination(List<int> numbers)
{
this.numbers = numbers;
}
public override string ToString()
{
return string.Join(";", this.numbers);
}
}
我没有机会完成整个程序,但我认为它会产生正确的结果。至少,显示了递归的想法。
答案 2 :(得分:-1)
如果我是你,我会检查回溯算法。它实际上构建了你需要的东西,但据我所知它耗费内存。
关于组合的数量,有公式: 100个组合中的100个组合等于:100!/ [10!*(100-10)!]