Интересные ответы. Спасибо за указатели на Википедию, хотя они и интересны, но на самом деле они не решают проблему, как я уже говорил, поскольку я искал точные совпадения, - скорее проблема учета / балансировки книг, чем традиционная проблема упаковки / ранцев.
Я с интересом следил за развитием переполнения стека и удивлялся, насколько это будет полезно. Эта проблема возникла на работе, и я подумал, может ли переполнение стека дать готовый ответ (или лучший ответ) быстрее, чем я мог бы написать его сам. Спасибо также за комментарии, предлагающие пометить это домашнее задание - я думаю, что это достаточно точно в свете вышесказанного.
Для тех, кто заинтересован, вот мое решение, которое использует рекурсию (естественно). Я также передумал насчет сигнатуры метода и выбрал List>, а не decimal [] [] в качестве возвращаемого типа:
public class Solver {
private List<List<decimal>> mResults;
public List<List<decimal>> Solve(decimal goal, decimal[] elements) {
mResults = new List<List<decimal>>();
RecursiveSolve(goal, 0.0m,
new List<decimal>(), new List<decimal>(elements), 0);
return mResults;
}
private void RecursiveSolve(decimal goal, decimal currentSum,
List<decimal> included, List<decimal> notIncluded, int startIndex) {
for (int index = startIndex; index < notIncluded.Count; index++) {
decimal nextValue = notIncluded[index];
if (currentSum + nextValue == goal) {
List<decimal> newResult = new List<decimal>(included);
newResult.Add(nextValue);
mResults.Add(newResult);
}
else if (currentSum + nextValue < goal) {
List<decimal> nextIncluded = new List<decimal>(included);
nextIncluded.Add(nextValue);
List<decimal> nextNotIncluded = new List<decimal>(notIncluded);
nextNotIncluded.Remove(nextValue);
RecursiveSolve(goal, currentSum + nextValue,
nextIncluded, nextNotIncluded, startIndex++);
}
}
}
}
Если вы хотите, чтобы приложение протестировало это, попробуйте этот код консольного приложения:
class Program {
static void Main(string[] args) {
string input;
decimal goal;
decimal element;
do {
Console.WriteLine("Please enter the goal:");
input = Console.ReadLine();
}
while (!decimal.TryParse(input, out goal));
Console.WriteLine("Please enter the elements (separated by spaces)");
input = Console.ReadLine();
string[] elementsText = input.Split(' ');
List<decimal> elementsList = new List<decimal>();
foreach (string elementText in elementsText) {
if (decimal.TryParse(elementText, out element)) {
elementsList.Add(element);
}
}
Solver solver = new Solver();
List<List<decimal>> results = solver.Solve(goal, elementsList.ToArray());
foreach(List<decimal> result in results) {
foreach (decimal value in result) {
Console.Write("{0}\t", value);
}
Console.WriteLine();
}
Console.ReadLine();
}
}
Надеюсь, это поможет кому-то еще быстрее получить ответ (будь то домашнее задание или иное).
Приветствия ...