I have the following recursion:
if(a%2 == 0){
f([a1,a2,...,aN],a,N) = (a1 + aN)/2 + f([a1,a2,...,a(N-1)],a+1,N-1)/2 +
f([a2,...,aN],a+1,N-1)/2;
}
else{
f([a1,a2,...,aN],a,N) = f([a1,a2,...,a(N-1)],a+1,N-1)/2 +
f([a2,...,aN],a+1,N-1)/2;
}
Base Case:
f([a1,a2],a,2) = (a1+a2)/2;
Obviously, there’ll be a stack overflow if I implement it recursively. How should I make use of Dynamic Programming to obtain optimal solution to this recursion?
[a1,a2,..,aN] respresents an integer array.
The limit for N is 2000 and a1,a2,..,aN <=999.
This smells an awful lot like a homework problem. I would suggest that you meet with the lecturer or a TA because this is the sort of thing best learned interactively. If you use this information, make sure to cite it so you don’t commit plagiarism.
First, observe that the results are linear in the values
[a0, a1, ... aN]. Therefore, you really only need to keep track of their coefficients. For notational purposes, let’s write{b1, b2, ..., bN}to representb1 * a1 + b2 * a2 + ... bN * aN.Next, work out a few of the recursions by hand:
f([a1, a2], a, 2) = { 1/2, 1/2 }is the base case forN=2.Let’s look at
N=3:f([a1, a2, a3], a, 3)foraeven ={1/2, 0, 1/2} + { f([a1, a2], a+1, 2)/2, 0 } + { 0, f([a2, a3], a+1, 2)/2 } = { 1/2, 0, 1/2 } + { 1/4, 1/4, 0 } + { 0, 1/4, 1/4 } = { 3/4, 1/2, 3/4 }.f([a1, a2, a3], a, 3)foraodd ={ f([a1, a2], a+1, 2)/2, 0 } + { 0, f([a2, a3], a+1, 2)/2 } = { 1/2, 0, 1/2 } + { 1/4, 1/4, 0 } + { 0, 1/4, 1/4 } = { 1/4, 1/2, 1/4 }.Now
N=4:f([a1, a2, a3, a4], a, 4)foraeven ={ 1/2, 0, 0, 1/2 } + { f[a1, a2, a3], a+1, 3)/2, 0 } + { 0, f([a2, a3, a4], a+1, 3)/2 }. Sinceais even,a+1is odd, so we are in the caseF([], even, 3).f([a1, a2, a3, a4], a, 4)foraeven ={ 1/2, 0, 0, 1/2 } + { 1/8, 1/4, 1/8, 0 } + { 0, 1/8, 1/4, 1/8 } = { 5/8, 3/8, 3/8, 5/8 }.f([a1, a2, a3, a4], a, 4)foraodd ={ f[a1, a2, a3], even, 3)/2, 0 } + { 0, f([a2, a3, a4], even, 3)/2 } = { 3/8, 1/4, 3/8, 0 } + { 0, 3/8, 1/4, 3/8 } = { 3/8, 5/8, 5/8, 3/8 }.Now you can see that the coefficients depend only on
Nand whetheraeven or odd.This means that your dynamic programming only needs to remember the coefficients for each combination of
Nand a boolean. SinceNis capped at 2000, this means you need only 4000 entries, which shouldn’t be too much of a burden. In fact, you could abandon the recursion and simply compute the entire table incrementally like we did above.