DP overview

Правка en13, от THE_THUNDERSTORM_BEGINS, 2025-09-24 00:30:08

this blog will talk about the info needed to solve DP problems in general.

DP or dynamic programming is a method used to solve bigger problems be dividing them in some way

however while learning DP i recommend being similar with some data structures , sometimes we might just need a set or a map but at expert level i recommend being familiar with segment tree data structure.

this blog will be divided into phases where i explain some basic DP problems or explain some DP method in general.

each phase will contain codes and examples , you can ask more questions in comments.

Overview

1.Fibonacci

sorry for this i really know this is what people tend to explain when doing DP but hear me out

the standard Fibonacci function looked something like this

int f(int n){
   if(n<1)return 0;
   return f(n-1)+f(n-2);
}

thinking about the complexity of this code , it appears that if takes O(f(n)) time complexity.

you should know that f(40)=102334155 so we may not be able to compute f(50) or anything greater with this function!.

or.. can we do something to make this even faster?

note that computing f(i) will call f(i-1) and f(i-2) but then calling f(i-1) will also call f(i-2) , so here is the catch , lets change our function so that whenever we are computing f(n) for a second time we return the previously computed answer, something like so

int mem[N],vis[N];
int f(int n){
    if(n<1)return 0;
    if(n==1)return 1;
    if(vis[n])return mem[n];
    vis[n]=1;
    return mem[n]=f(n-1)+f(n-2);
}

what is the complexity now? , turns out it is O(N) as we may compute each item at most once and the rest will be returned in O(1).

this is the trick behind (some) DP methods , but knowing this method we will jump into some actual problems that use it.

Frog 1

no comment needed , you may just observe how similar this is to Fibonacci (or you might just jump to solve it directly).

The solution

your task is now to try and solve Frog 2.

2. more conditions

previously we only needed to handle one state where as in most cases we may need more , it is really funny how some people solve DP problems with 7 states and you see their code like how are you even understanding this!.

lets go even deeper , two states it is , and the problem Vacation might be a best choice for this.

the solution
i recommend you seeing the previous solutions

3.Knapsack

this problem was really pain to understand at first , and it is not really present in the contest as long as i can see, we will now talk about Knapsack 1.

in this problem we have to compute dp(W) as the maximum profit from a capacity of W, now we need to know how to compute it using previous states , when we use an item we add ts value and subtract its weight like so

dp(W)=max(dp(W-w[i])+v[i])

but this way we may use an item more than once (the problem).

and so we may need to add extra state to know which items were used

our state will be dp[W][1<<100] (just kidding this is impossible ).

i will leave you to think on how to solve this.

the solution

try to solve Knapsack 2 !

Hint!

4.Tracing

Ok! now we are able to find the minimum,maximum whatsoever but how do we actually know how we reached the answer? like in Knapsack how do we know what items we choose?

till now we used only two arrays mem(the answer),vis(did we calculate it before?)

now we will use another array to know from which state we got our best answer after calculating the answer we use this array to trace it.

we will present this in a simple problem like this problem this problem was solved once and i saw 2 or maybe more standard problems like it,

the state was like dp[index in S][index in T]

but knowing the transition might be hard so i will leave you to think!

the transitions

this way we made sure we tried all cases

we tried matching the current positions and incrementing each index by one,and so (somehow!) we can say we tried every case and got the best answer in the end!.

the code for the answer would be something like this

c++

5.Time complexity

a main issue in DP as we really need to calculate this before going forward with our solution. the time complexity is simply sum of number of operations in all states

for simplicity i usually calculate the complexity of the dp function and multiply this by the number of states (this is not precise in general)

we will go forward with an example Candies

at first glance you might think you knew the solution, but usually you will get a TLE , why?.

lets say your dp function looked like this:

for(int j=0;j<=min(a[i],k);j++){
    res+=dp(i+1,k-j);
}

what is the complexity of this?

for each dp[index][number of candies] we will loop (in worst case) on the number of candies, which means our complexity is n*k*k (an absolute disaster) we will have to get this loop in O(1) for this to work.

i recommend you try to solve it.

Hint!
the solution

6.DP left right

this kind is as easy as it sounds (maybe the most unexpected answer for a problem)

you might even be able to solve the Deque problem yourself

the idea is to get the answer of an array by getting the answer of some sub arrays .

lets try to solve the problem

the state is as following:

spoiler

knowing this we can do two transitions:

spoiler

so the answer would look like:

c++

Break

here we are actually done with standard DP

from now on we will tend to explain somethings in short and less explained way

till now the learned info is more than enough till expert level or even master level

after this there will a bunch of hard topics that are considered DP approach (each one may need a whole new blog).

you now are able to solve these:

Longest Path

Grid 1

Coins

Hint!

Stones

7.DP with a trick

this trick was so amazing when i learned it

in the past we learned that DP goes in a single direction but what if the DP calls itself?

here is an example Sushi

the state of the DP here is

spoiler

you may try to solve this on your own at first

the solution

История

 
 
 
 
Правки
 
 
  Rev. Язык Кто Когда Δ Комментарий
en18 Английский THE_THUNDERSTORM_BEGINS 2025-09-24 02:41:46 2 Tiny change: ' $dp[W][2^100]$ (just k' -> ' $dp[W][2^{100}]$ (just k'
en17 Английский THE_THUNDERSTORM_BEGINS 2025-09-24 02:38:34 196 (published)
en16 Английский THE_THUNDERSTORM_BEGINS 2025-09-24 02:00:14 2760
en15 Английский THE_THUNDERSTORM_BEGINS 2025-09-24 01:31:55 1379 Tiny change: '</spoiler>' -> '</spoiler>\n\n\n'
en14 Английский THE_THUNDERSTORM_BEGINS 2025-09-24 01:13:10 2199 Tiny change: ' answer.\n\n$$\ndp[L' -> ' answer.\n$$\ndp[i][i]=0\n$$\n$$\ndp[L'
en13 Английский THE_THUNDERSTORM_BEGINS 2025-09-24 00:30:08 2149
en12 Английский THE_THUNDERSTORM_BEGINS 2025-09-23 18:22:08 2425 Tiny change: 'c3])\n$$\n$$\n+\frac' -> 'c3])\n$$\n $$\n+\frac'
en11 Английский THE_THUNDERSTORM_BEGINS 2025-09-23 17:49:26 2593
en10 Английский THE_THUNDERSTORM_BEGINS 2025-09-23 03:48:42 56
en9 Английский THE_THUNDERSTORM_BEGINS 2025-09-23 03:39:19 10
en8 Английский THE_THUNDERSTORM_BEGINS 2025-09-23 03:38:22 600
en7 Английский THE_THUNDERSTORM_BEGINS 2025-09-23 03:26:18 27
en6 Английский THE_THUNDERSTORM_BEGINS 2025-09-23 03:25:43 2373
en5 Английский THE_THUNDERSTORM_BEGINS 2025-09-23 03:02:28 2810
en4 Английский THE_THUNDERSTORM_BEGINS 2025-09-23 02:32:47 1458 Tiny change: 'oiler>\n\n\n' -> 'oiler>\n\nyour task is now to try and solve \n\n\n'
en3 Английский THE_THUNDERSTORM_BEGINS 2025-09-23 02:18:44 680
en2 Английский THE_THUNDERSTORM_BEGINS 2025-09-23 02:10:17 1413 Tiny change: 'ike this\n```\nint' -> 'ike this\n\n```\nint'
en1 Английский THE_THUNDERSTORM_BEGINS 2025-09-23 01:54:07 817 Initial revision (saved to drafts)