你可以使用递归来实现。
算法的思路如下:
- 在每次执行中,你需要遍历区间内所有可能的数字。
- 通过递归调用生成下一个区间的数字。
- 如果在任何时候求和超过所需值,则回溯。
- 一旦生成了所有数字,如果总和等于所需数字,则拥有一种可能的组合。
这个方案可以改进,但它是可行的解决方案。
以下代码将在控制台中打印所有有效序列:
SplitNumber(100, new Interval[]
{
new Interval { Min = 0, Max = 11 },
new Interval { Min = 0, Max = 11 },
new Interval { Min = 0, Max = 40 },
new Interval { Min = 0, Max = 40 },
});
public static void SplitNumber(int n, Interval[] intervals)
{
SplitNumber(n, 0, intervals, "");
}
public static void SplitNumber(int n, int k, Interval[] intervals, string s)
{
if (n < 0) return;
if (k >= intervals.Length) { if (n == 0) Console.WriteLine(s); }
else
for (int i = intervals[k].Min; i <= intervals[k].Max; i++)
SplitNumber(n - i, k + 1, intervals, string.Format("{0} {1}", s, i));
}
Interval
类大致如下:
public class Interval
{
public int Min { get; set; }
public int Max { get; set; }
}