This is another Python solution, but hopefully it will be easy for you to convert it to PHP (I would do it myself, but I'm not a PHP expert - Iβm sure that you could deal with this better). I tried not to use any advanced Python features, so readers who don't use Python are easier to understand, but if some of the Python syntax is not clear, just ask.
allowed = [3, 5, 6, 9, 10] n = 28 solutions = [ None ] * (n + 1) solutions[0] = [] for i in range(n + 1): if solutions[i] is None: continue for a in allowed: if i + a > n: continue if solutions[i + a] is None or len(solutions[i]) + 1 < len(solutions[i + a]): solutions[i + a] = solutions[i] + [a] print solutions[28]
It works, starting from 0 and creating to the desired number, while maintaining the cache of the shortest solution, visible so far for each possible result. It has an O (n * a) runtime, where a is the number of different valid values.
By the way, your answer to n = 28 is incorrect. It should be [9, 9, 10].
Update: here is my attempt to solve PHP:
<?php $allowed = array(3, 5, 6, 9, 10); $n = 28; $solutions = array(); $solutions[0] = array(); foreach (range(0, $n) as $i) { if (is_null($solutions[$i])) continue; foreach ($allowed as $a) { if ($i + $a > $n) continue; if (is_null($solutions[$i + $a]) || sizeof($solutions[$i]) + 1 < sizeof($solutions[$i + $a])) { $solutions[$i + $a] = array_merge($solutions[$i], array($a)); } } } var_dump($solutions[$n]); ?>
It gives the correct answer, but please keep in mind that I am not a professional PHP encoder - I was just looking for equivalent functions in the PHP documentation.