Я думаю, вы можете решить это, построив дерево.
На каждом узле у вас есть список значений. Предполагая, что сумма этого списка меньше требуемой суммы - назовем это S - вы можете создать не более трех дочерних элементов для этого узла: один, добавив 1 в список этого узла, один, добавив 2, и один, добавив 3 Условием для создания ребенка будет то, что сумма в новом списке будет по-прежнему меньше, чем S.
В конце, то есть когда вы не можете генерировать новые узлы, у вас есть все ваши последовательности в узлах вашего дерева.
РЕДАКТИРОВАТЬ: в C # мое плохое объяснение даст что-то вроде этого:
первый:
public class Node
{
public Node()
{
Children = new List<Node>();
}
public static int SumMax { get; set; }
public List<int> Values { get; set; }
public List<Node> Children { get; set; }
public void AddChild(int data)
{
if (Values.Sum() + data < SumMax)
{
Node child = new Node();
child.Values = new List<int>(Values);
child.Values.Add(data);
Children.Add(child);
for (int = data; i < 4; i++)
{
child.AddChild(i);
}
}
}
public void FillSequences(List<List<int>> sequences)
{
if (Values.Count != 0)
{
sequences.Add(Values);
}
foreach (Node child in Children)
{
child.FillSequences(sequences);
}
}
}
тогда основной:
void Main()
{
Node.SumMax = 10;
Node root = new Node();
root.Values = new List<int>();
for (int i = 1; i < 4; i++)
root.AddChild(i);
List<List<int>> sequences = new List<List<int>>();
root.FillSequences(sequences);
//here you've got your sequences results in "sequences" and you can do what you want
}
Я не знаю, достаточно ли это стандартно, но примерно выполняет свою работу. Я надеюсь, что это соответствует вашим потребностям ...
РЕДАКТИРОВАТЬ : чтобы избежать генерации одинаковых последовательностей, мы можем «упорядочить» дерево: узел не может генерировать дочерний элемент с более низким значением, чем его. Таким образом, в методе AddChild мы начинаем цикл с «данных», а не с 1.