1

I have the following recursive function:

typedef unsigned long long ull;

ull calc(ull b, ull e)
{
  if (!b) return e;
  if (!e) return b;
  return calc(b - 1, e - 1) + calc(b - 1, e) - calc(b, e - 1);
}

I want to implement it with dynamic programming (i.e. using storage). I have tried to use a map<pair<ull, ull>, ull> but it is too slow also. I couldn't implement it using arrays O(1) too.

I want to find a solution so that this function solves quickly for large b, es.

7
  • I'm not sure I get the question right, so could you clarify what exactly do you want: do you want to get rid of the recursion, or do you just want to change the way you store data? Commented Jul 3, 2012 at 7:15
  • @SingerOfTheFall I understand recursion, but I want to speed this function up Commented Jul 3, 2012 at 7:17
  • The obvious optimization is to use a cache, possibly implemented as a hash map. Commented Jul 3, 2012 at 7:17
  • can't you do it this way DP[0][e] = e DP[b][0] = b and then DP[b][e] = DP[b-1][e-1] + DP[b-1][e] - DP[b][e-1] Commented Jul 3, 2012 at 7:17
  • @sukunrt Then, what is the value of DP[0][0] ?? Commented Jul 3, 2012 at 7:18

4 Answers 4

5

Make a table b/e and fill it cell by cell. This is DP with space and time complexity O(MaxB*MaxE).

Space complexity may be reduced with Ante's proposal in comment - store only two needed rows or columns.

0 1 2 3 4 5
1 0 3 . . .
2 . . . . .
3 . . . . .
4 . . . . .
Sign up to request clarification or add additional context in comments.

2 Comments

beat me by about 15 seconds :).
It is enough to store current and last row or column. Space required is O(min(MaxB,MaxE)).
2

If a bottom up representation is what you want then this would do fine.

Fill up the table as MBo has shown

This can be done as:

for e from 0 to n:
  DP[0][e] = e
for b from 0 to n:
  DP[b][0] = b
for i from 1 to n:
   for j from 1 to n:
      DP[i][j] = DP[i-1][j-1] + DP[i-1][j] - DP[i][j-1]

now your answer for any b,e is simply DP[b][e]

2 Comments

DP[0][0] once == e and then == b ??
Both the times it's 0. Doesn't make a difference.
2

You might want to take a look at this recent blog posting on general purpose automatic memoization. The author discusses various data structures, such std::map, std::unordered_map etc. Warning: uses template-heavy code.

Comments

1

You can implement in O(n^2) (assuming n as max number of values for b and e ) by using a 2 dimensional array. Each current value for i,j would depend on the value at i-1,j and i-1,j-1 and i,j-1. Make sure you handle cases for i=0, j=0.

2 Comments

Ok, if we look at b, e they can be in 3 cases: b > e, b < e, b == e. At 3 cases, we cannot guarantee that a value exists in DP[0][0]?
You are doing this bottom up so this condition won't happen. Can you explain with an example?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.