Sunday, August 27th
A river-crossing frog
Given an arrangement of stones, and the ability of a frog to jump k-1, k, or k+1 distances, determine if the frog can successfully cross the river
A variegated golden frog, taken by Charles J. Sharp, distributed by via Wikipedia under the Creative Commons Attribution-Share Alike 4.0 International license. No changes madeThe dependencies of previous answers to later answers demonstrates overlapping subproblems, and is a candidate for solving with dynamic programming.
We first identify our state variables. What does each subproblem consist of? There is the frog's index on the stones array, we are trying to find if the frog can travel from one index to the last index. Also, since the distance a frog can jump depends on the previous jump, the second state variable is the length of the previous jump.
With the state variables in mind, we can begin developing the dynamic programming recursive function dp. It accepts 2 variables, the index i, and the previous step k. The function will return true a route can be found, false if otherwise.
The first condition to test for is if we have reached the end of the river. If so, return true;
Next, since this is dynamic programming, we need to develop a memo for storing intermediate results. The memo will be 2 dimensions, for each state. variable. The problem constraints limits the size of the river to 2000 stones, so our position index and step length will be capped by 2001.
Additionally, we initialize a map that maps stone positions to indices. This will be used when testing if a given frog jump lands on a stone. For convenience, to restrict the number of arguments to the dp function, we make the stones input array a global variable
...
Back in the dp function, we test if a given state has already been calculated
Now we come to the recurrence relation. There are three possible state transitions, one for each type of step, whether, with k begin the length of the previous jump, k-1, k, or k+1 jump lengths. For each step length, we create a boolean variable
Then for each variable, we determine if a jump of that length is possible. Using the map, we test if a jump will land on a stone, and if it does, recursively call the dp() function with updated state variables for index and jump size.
First we use the stone map, sm, to test if such a stone exists, eg
sm.find(stones[i] + k) != sm.end()
And if so, we call the function recursively, with the index updated and step updated, e.g.
For a step of the same size:
For a step of one less, we also make sure it's not a non-jump
And for jump lengths of k+1
To complete the dp function, we update the memo using a logical OR of the three recursive calls and return the result
Finally, we add the initial recursive call to the main function
A two state dp problem, with the added complexity of the reverse lookup map
Thanks to user shivam-727 for organizing the dp function into 3 boolean variables
Comments
Post a Comment