Best paper awards at ICALP 2012
-
The preliminary version of the detailed programme for ICALP 2012 is now
available here. While skimming through the programme, I learnt that the
best paper ...
38 minutes ago
Isn't a recursive function? I am thinking the solution as a tree, the number of leaf nodes is our target. Mathematically,
ReplyDeleteF(N) = 1 if N = 1
= 2 if N = 2
= 4 if N = 3
= F(N-1) + F(N-2) + F(N-3) if N > 3
Any comments?
This blog is so much better than watching TV :)
ReplyDeleteSo this is I think best to solve with a tree algorithm as Venkata suggested earlier. An initial naive solution might be to use a simple breadth first search like:
static Stack<long> nodes = new Stack<long>();
static long Combinations( int n )
{
long leafs = 0;
nodes.Push(n);
while (nodes.Count > 0)
{
var x = nodes.Pop();
// Leaf, just count
if (x <= 0) leafs++;
else
{
// Only push down options where the child can actually complete
// the stair jump on a complete jump (i.e. not taking last 1 step in a 3step jump)
if (x - 1 >= 0) nodes.Push(x - 1);
if (x - 2 >= 0) nodes.Push(x - 2);
if (x - 3 >= 0) nodes.Push(x - 3);
}
}
return leafs;
}
But it is soon obvious that for non-trivial N then this naive BFS is simply too slow.
However when looking at the ternary-tree it becomes obvious that it is simply a repeating pattern of the same subtrees. So enhancing this algorithm to be recursive and having a simple caching map for previously calculated subtrees drastically improves performance. Like so:
static Dictionary<int, BigInteger> map = new Dictionary<int, BigInteger>();
static BigInteger Combinations2(int n)
{
// Wooha, at a leaf
if (n <= 0) return 1;
BigInteger leafs = 0;
if (map.TryGetValue(n, out leafs))
return leafs;
// We need to calculate it if not found
if (n - 1 >= 0)
leafs += Combinations2(n - 1);
if (n - 2 >= 0)
leafs += Combinations2(n - 2);
if (n - 3 >= 0)
leafs += Combinations2(n - 3);
map[n] = leafs;
return leafs;
}
At least Combinations2 is a little bit more intelligent than before :)