Minimum number of jumps
A classical question is the minimum number of jumps problem. Instances of this problem are usually of the following form
Find the minimum number of jumps needed to get from a starting point X to an end point Y given a number of possible steps per each subposition
Easier instances have a fixed distance per each intermediate step. Harder instances use an array of distances available to move forward at each subposition. E.g. given the following vector
\[v = \{2,1,1,4\}\]and let position (0-based) \( X=0 \) be the start position and \( Y=3 \) be the end position, find the minimum number of jumps to go from \( X \) to \( Y \).
There are two possible paths:
\[p_1 = \{ 2 \to 1 \to 1 \to 4 \} \\ p_2 = \{ 2 \to 1 \to 4 \}\]Since \( p_2 \) only uses 2 jumps, it is the path using the minimum number of jumps we were searching for.
A recursive approach covering the entire search space (i.e. starting at \( X \) and recursively proceeding from every reachable new index) would be \( O(n!) \).
However a dynamic programming approach is available since the problem exhibits overlapping subproblems and optimal substructure: it is possible to determine an optimal number of jumps per each subset of the input indices.
#include <iostream>
#include <algorithm>
#include <vector>
#include <limits>
using namespace std;
int minJumps(const vector<int>& vec) {
// All states are unreachable at the beginning
vector<int> jumpsFrom0ToReach(vec.size(), numeric_limits<int>::max());
jumpsFrom0ToReach[0] = 0; // Base case
for (int i = 1; i < vec.size(); ++i) { // For each substate
for (int j = 0; j < i; ++j) { // For each state before i-substate
if (jumpsFrom0ToReach[j] != numeric_limits<int>::max() && // Can be reached
j + vec[j] >= i) { // Can reach/surpass i
jumpsFrom0ToReach[i] = min(jumpsFrom0ToReach[i], jumpsFrom0ToReach[j] + 1);
}
}
}
return jumpsFrom0ToReach.back();
}
int main() {
vector<int> vec = { 2, 1, 1, 4 };
cout << minJumps(vec); // 2
return 0;
}
The dynamic programming solution is \( O(N^2) \). One should always check the previous indices, i.e. in the array
\[v = \{ 1, 3, 2, 10, 9, 2, 4, 1, 6 \}\]at position \( i = 4\), the subindex \( j = 1 \) could reach \( i \) in less jumps than any other index.