Блог пользователя Chess.Master

Автор Chess.Master, 3 года назад, По-английски

Hello codeforces. I noticed that most of Experienced Programmers prefer Iterative DP over Recursive one. I Know that some hard problem need space optimizations that can be done in iterative only. But I found that they always use the iterative DP. I see that the recursive DP is much easier. So what is the real purpose of that? Is the iterative solution is easier for them !?

  • Проголосовать: нравится
  • +25
  • Проголосовать: не нравится

»
3 года назад, скрыть # |
← Rev. 2  
Проголосовать: нравится +18 Проголосовать: не нравится

Because iterative DP is faster. And recursive DP would cause Maximum call stack size exceeded sometimes.

»
3 года назад, скрыть # |
 
Проголосовать: нравится -7 Проголосовать: не нравится

Recursive dp is easier because you need not worry whether the value needed for the subproblems have been computed before or not. The value required, if computed before gets returned. If not computed, it will get computed and returned.

»
3 года назад, скрыть # |
 
Проголосовать: нравится +52 Проголосовать: не нравится

I don't know about others but I often find iterative dp easier to visualize.

»
3 года назад, скрыть # |
 
Проголосовать: нравится +7 Проголосовать: не нравится

Because...it is very hard to pass using a recursive DP solution in Python

»
3 года назад, скрыть # |
 
Проголосовать: нравится +19 Проголосовать: не нравится

I prefer recursive dp as it is easier to imagine for me and rarely there's a problem that needs iterative instead. Iterative is faster

»
3 года назад, скрыть # |
 
Проголосовать: нравится +30 Проголосовать: не нравится

I guess iterative dp is faster and possibly more memory-efficient depending on how it's coded, but that's rarely an issue.

I use iterative dp basically always. It's just more intuitive for me.

  • »
    »
    3 года назад, скрыть # ^ |
    ← Rev. 2  
    Проголосовать: нравится 0 Проголосовать: не нравится

    And this is what i am asking for. Why the iterative is intuitive for you ? I found that almost all the orange and red coders write the iterative dp. How ? and Why ?

    • »
      »
      »
      3 года назад, скрыть # ^ |
       
      Проголосовать: нравится 0 Проголосовать: не нравится

      Why do you find iterative dp difficult?

      • »
        »
        »
        »
        3 года назад, скрыть # ^ |
         
        Проголосовать: нравится 0 Проголосовать: не нравится

        I can't visualize it in my mind. I always find the recursive easy to visualize in my mind. I define the parameters for my recursive function and the write the base case .. add the memorization .. and that's all!

        • »
          »
          »
          »
          »
          3 года назад, скрыть # ^ |
          ← Rev. 3  
          Проголосовать: нравится +47 Проголосовать: не нравится

          All you need to do to make iteratve dp from recursive is to define the order of the calculations.

          One can visualize dp as a DAG, where vertices are states and edge (u, v) means that state u is required to calculate state v.

          For example, take Fibonacci sequence as a simpliest dp. You have vertices from 1 to n, and edges (u, u + 1) and (u, u + 2). States (vertices) without edges coming in, should have values known before computation (F(1) = 1, F(2) = 1).

          You can observe that for every edge (u, v) there is always u < v, so, instead of writing recursion, you can just iterate from 1 to n.

          So, you need to iterate in such a way that for each edge (u, v) state u is calculated strctly before state v.

          You can apply this interpretation to some other dps to better understand this approach.

          P.S. By the way, there are also dps on trees and on DAGs.

      • »
        »
        »
        »
        3 года назад, скрыть # ^ |
         
        Проголосовать: нравится 0 Проголосовать: не нравится

        But Once i write the recursive solution i find it easy to convert it to iterative one !!|

        For example 217430558 217434592

        • »
          »
          »
          »
          »
          3 года назад, скрыть # ^ |
           
          Проголосовать: нравится +9 Проголосовать: не нравится

          Ah, so you can easily go from a solution idea to the recursive implementation and then, you can do the iterative implementation. But going straight to the iterative implementation is difficult.

          If you want to learn to do X, you need to practice doing X.

          If you want to write iterative dp easily without writing recursive first, you just need to try to do it — you'll get better the more you practice.

»
3 года назад, скрыть # |
 
Проголосовать: нравится -62 Проголосовать: не нравится

Don't fall into the trap of IGMs and GMs saying that iterative DP is faster. Everybody does it because it looks cool. I want my code to look cool that is why I use iterative DP. I don't want to look like a noob who can't visualize iterative DP and is stuck on recursive approach.

  • »
    »
    3 года назад, скрыть # ^ |
    ← Rev. 2  
    Проголосовать: нравится 0 Проголосовать: не нравится

    But the Iterative is faster than the recursive due to the function call overhead as the function calls can be relatively slow compared to simple iterative operations. Each function call adds overhead for parameter passing, creating a new stack frame, and managing the call and may consume more memory due to the call stack that keeps track of function calls. This can lead to stack overflow errors for large inputs.

    The recursive only be faster in some few cases as sometimes it calculate only what it need to calculate while the iterative solution always calculate everything

  • »
    »
    3 года назад, скрыть # ^ |
     
    Проголосовать: нравится +40 Проголосовать: не нравится

    Why? Iterative dp is clear as long as you know dp_{something} means something and how it can be transitioned. Recursive dp is slow and when you try to optimize the dp using something it may be unclear.

  • »
    »
    3 года назад, скрыть # ^ |
     
    Проголосовать: нравится 0 Проголосовать: не нравится

    iterative IS faster, but there aren't many problems that actually need you to do iterative instead.

  • »
    »
    3 года назад, скрыть # ^ |
    ← Rev. 2  
    Проголосовать: нравится 0 Проголосовать: не нравится

    IGMs and GMs, as you said, saying that iterative DP is faster for a reason, becuase it IS actually faster. For example, it can be optimized by compiler if it involves simple operations, or, for 2d/3d DPs, if some layers are copied, one can use memcpy for optimization.

    It takes less time to code than recursive DP. Also understanding the concept of iterative DP will help you to understand DP that use binary matrix exponentation.

    Of course, there are some problems, where recursive DP is a lot more convenient, for example dp on trees or dp on DAGs. But these DPs most commonly are assotiated with DFS and not with recursive DP.

  • »
    »
    3 года назад, скрыть # ^ |
    ← Rev. 2  
    Проголосовать: нравится +17 Проголосовать: не нравится

    It's not a matter of looking cool. Using myself as an example, I started out coding most DPs recursively but I transitioned to iterative because of a mix of getting tired of TLE due to recursion overhead/cache misses, iterative dp allowing some optimizations that recursive doesn't allow (such as using a segment tree to aid in transitions) and iterative usually just being less code (3-4 lines instead of 8-10 lines for recursive).

  • »
    »
    3 года назад, скрыть # ^ |
     
    Проголосовать: нравится -16 Проголосовать: не нравится

    I really appreciate all the people who are trying to prove why iterative dp is better and trying to educate others. But PS my comment was just written in humour, take it lightly.

  • »
    »
    3 года назад, скрыть # ^ |
     
    Проголосовать: нравится 0 Проголосовать: не нравится

    hey i remember you from yt, you make great videos :)

»
3 года назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

I always use recursive DP if the problem accepts such solutions. It's way easier to debug and you always respect some kind of template.

»
3 года назад, скрыть # |
 
Проголосовать: нравится +5 Проголосовать: не нравится
»
3 года назад, скрыть # |
← Rev. 3  
Проголосовать: нравится +7 Проголосовать: не нравится

It depends on the situation. Ie sometimes the problem calls for DP on a tree, in which recursive DP is much more convenient. Usually, experienced programmers will go for whatever is easier to implement in a given problem.

One problem with recursive DP is if the calls get very deep. I find that for example, a DFS on 50 million nodes often times out, and am not sure why. I suspect that the constant factor gets large when the stack size is large due to cache reasons.

»
3 года назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

I prefer iterative dp for two reasons:

  1. I am more comfortable in debugging it.
  2. I can do memory optimisation with iterative dp.
»
3 года назад, скрыть # |
← Rev. 4  
Проголосовать: нравится +19 Проголосовать: не нравится

There are two ways to write iterative dp, pull dp and push dp:

vector dp(n + 2, 0ll);
dp[1] = 1;

// push
for (int i = 1; i < n; i++) {
    dp[i+1] += dp[i];
    dp[i+2] += dp[i];
}

// pull
for (int i = 2; i <= n; i++) {
    dp[i] = dp[i-1] + dp[i-2];
}

push DP is much harder to visualize for me, but pull dp looks exactly like recursive, except you need to write out base cases, which is a bit tedious (that's why I usually write recursive first).

Example, as you can see it hardly differs except the base cases:

Spoiler
»
3 года назад, скрыть # |
 
Проголосовать: нравится +6 Проголосовать: не нравится

Another reason of using iterative DP is the ease of debugging. I myself find debugging a recursive DP implementation specifically, or any recursive function generally, quite horrendous. Iterative DP is easier to debug since you're literally calculating values from the bottom up, hence you can keep track of the current result; while in recursive DP you'll be lead to a seemingly random state whose value hasn't been calculated yet and jumping from state to state almost indefinitely.

That being said, I still use recursive DP 80% of the time because of it's simpler thinking process. Recursive DP functions look almost the same as each other, you can immediately start implementing it like a no brainer and it would highly likely be correct if your recurring formula is also correct. Once you've came up with a recurrence, with recursive DP you'll only need to specify the base cases while for iterative DP you also have to additionally determine the looping order of calculating. Determining this is sometimes not very trivial or straight up impossible, for instance Knapsack DP.

»
3 года назад, скрыть # |
← Rev. 2  
Проголосовать: нравится -6 Проголосовать: не нравится

To the experts, I have an additional question. Is recursive dp more time-consuming than iterative dp? if yes, what is the reason?

»
3 года назад, скрыть # |
← Rev. 2  
Проголосовать: нравится +16 Проголосовать: не нравится

i personally use iterative dp, because i realized recursive and iterative dp are the same except for looping order which is (nearly) always easy to find out [idk any cases where its hard, but maybe they exist] and iterative allows for optimizations, while recursive doesnt.

Why would i use recursive is the real question

»
3 года назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

I think its more of a habit thing , first someone tells you its fast , then you start doing it , then it becomes easier, personally I have never written recursive dp and when I tried it I found iterative dp way more intuitive and easier.

»
3 года назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

I don't like recursion unless it's dfs

»
3 года назад, скрыть # |
← Rev. 3  
Проголосовать: нравится +9 Проголосовать: не нравится

Depends on the problems. Sometimes I use recursive dp because it can be nicely implemented. Sometimes iterative dp is harder. When transitions are too complex, the only choice is recursive dp.

»
3 года назад, скрыть # |
 
Проголосовать: нравится -26 Проголосовать: не нравится

it is faster and better memory but it is hard i think the recurive one is much more easier so if it fits in recursive solution do it if not apply iterative. experienced programmers do it because it is cooler; if recursive solution work do it without thinking