Dynamic Programming
Dynamic Programming
The basic theory of dp is pretty simple, but to apply the knowledge, we require a lot of practices, practicing == mastering, its extremely true for dp . And the fun is that too many problems can be solved with dp, its one kind of optimized brute force, which can solve many problems surprisingly fast . To learn dp, we start from the very beginning [ its not for advanced reader, so Im not differentiating between dp & Memoization, there is no problem to call both dp ] Given n numbers, you have to print their sum How would you do that ? scanf(%d,&n) ; int sum = 0 ; for(i=0;i<n;i++) { scanf(%d,&in[i]) ; sum = sum + in[i] ; } Simpe, isnt it ? you can say youve solved a dp problem :D
How ? dp means to solve a problem, break it into subproblems, solve them, & get your answer from them Let call dp[i] = sum of numbers indexed from 0 to I ; So, youll have to find dp[n-1], ok? Now, lets break it into subproblems, cant we say dp[i] = dp[i-1] + in[i] ; . ? so , we can find the solution from the recursive call bool visited[MAX] = {0} ; int cal( int i ) { If(i<0) If(visited[i])
Visited[i] = 1 ; return dp[i] = in[i] + cal(i-1) ; } So, if we say, youll be given 100 numbers, & then 10000000 queries, each giving i as input, & you are to print in[0] + in[1] + .. + in[i] .. you can do this dp [ advanced coders call it memoization, but you can call dp ] If you dont do this memoization, youll get tle [ why?i think you know ]
.. so to solve dp , we need to do things 1. 2. 3. define state [ here i is state ] derive the recursive solution [ here dp[i] = in[i] + dp[i1] ] find base case
& its over :D What is state ? its the position where the problem is strictly defined and we can give a solution To define the state, be carefull, make sure itll end up to the base case, it must not be cyclic . Int cal(int i) { If(i<0 || i==n) return 0 ; If( isV[i] ) return dp[i] ;
dp[i] = in[i] + cal(i+1) + cal(i-1) ; isV[i] = 1 ; Return dp[i] ; } . What do you think about this dp ??? :D:P
Now . Find nth Fibonacci number modulo 1007 [ n<=10000 ] I know you can solve it with dp[ or memoization [ hint: dp[i] = dp[i-1] + dp[i-2], & you need two base cases as there are two terms in the recursive call ] ] and you know, (a+b)%M = (a%M + b%M ) % M Now solve it given n & r, find nCr[you know what it is] modulo 1007 n<=1000, r<=1000, there will be 1000000 test cases Its very basic idea of dp to start learning + practicing Types of DP : There are many types, you can master them with practising , & can apply the same idea in many problems You can learn some standard dp problem solutions like knapsack, coin change, matrix chain multiplication, rock climbing, tsp etc etc but I think you should think about the problem & make out a solution yourself, & its not tough if you know the raw idea of dp Solve the following problems
A. Memoization
1. http://uva.onlinejudge.org/external/107/10721.html 2. http://uva.onlinejudge.org/external/110/11069.html [a graph problem] http://uva.onlinejudge.org/external/109/10918.html [Tri Tiling] Probability/Expected Value
1. http://uva.onlinejudge.org/external/117/11762.html [Race to 1 ] 2. http://uva.onlinejudge.org/external/111/11181.html[Probability|
[Partitioning
by