Technically speaking, the runtime is O(1) because there is an upper bound on the size of the input (specifically, 32). But let's assume for a minute that the problem size isn't at most 32 and think about that problem. In that case, the runtime is O(n2). After a recursive call of some size has been made, any future recursive calls of the same size run in time O(1). This is due to the use of memoization in the dp
table. This means that we can compute the total runtime by summing up, across all possible recursive calls that could be made, the amount of time required to fill in the dp
table.
On a call of size n, there is O(n) work done to fill in the array. You can see this by the for loop that starts at 4 and counts up to n by two's, at each point doing O(1) work. Since the recursive calls are on sizes 0, 1, 2, ..., n, we have O(n) calls doing O(n) work each for a total of O(n2) total work.
Hope this helps!