I have a list of numbers like 1,2,3 and I want to find all the combination patterns that sum up to a particular number like 5. For example:
Sum=5
Numbers:1,2
public static List<List<string>> Partition(int n, int max, string prefix)
{
if (n == 0)
{
_results.Add(prefix.Split(new char[] { ',' }).ToList());
}
for (int i = Math.Min(max, n); i >= 1; i--)
{
Partition(n - i, i, prefix + "," + i);
}
return _results;
}
This is a slight modification of the change making problem. You should be able to find plenty of papers on this problem, and a dynamic programming solution would take no more than 20 lines of code.
http://en.wikipedia.org/wiki/Change-making_problem
This problem is known as a "doubly restricted integer partition." If the numbers "allowed" to sum to 5 were from a set V, then it is known as "multiply restricted integer partition." There is a paper by Riha and James: "Algorithm 29: Efficient algorithms for doubly and multiply restricted partitions" Computing Vol 16, No 1-2, pp 163-168 (1976). You should read that paper and implement their algorithm. Understanding how to do it will allow you to implement optimizations unique to your specific problem.
You can use following code .. it wiil give you a exact answer as you want..
void print(int n, int * a)
{
int i ;
for (i = 0; i <= n; i++)
{
printf("%d", a[i]);
}
printf("\n");
}
void integerPartition(int n, int * a, int level)
{
int first;
int i;
if (n < 1)
return ;
a[level] = n;
print(level, a);
first = (level == 0) ? 1 : a[level-1];
for(i = first; i <= n / 2; i++)
{
a[level] = i;
integerPartition(n - i, a, level + 1);
}
}
int main()
{
int n = 10;
int * a = (int * ) malloc(sizeof(int) * n);
integerPartition (n, a, 0);
return(0);
}
This might also help: Dynamic Programming: Combination Sum Problem
These are called the partitions of a number , and your problem seems to impose the constraint of which numbers you're allowed to use in the partition.