Count minimum factor jumps required to reach the end of an Array

Given an array of positive integers arr[], the task is to count the minimum factor jumps required to reach the end of an array. From any particular index i, the jump can be made only for K indices where K is a factor of arr[i].

Examples:

Input: arr[] = {2, 8, 16, 55, 99, 100}
Output: 2
Explanation:
The optimal jumps are:
a) Start from 2.
b) Since factors of 2 are [1, 2]. So only 1 or 2 index jumps are available. Therefore jump 1 index to reach 8.
c) Since factors of 8 are [1, 2, 4, 8]. So only 1, 2, 4 or 8 index jumps are available. Therefore jump 4 indices to reach 100.
d) We have reached the end, so no more jumps are required.
So, 2 jumps were required.

Input: arr[] = {2, 4, 6}
Output: 1

Approach: This problem can be solved using Dynamic Programming.



  1. Firstly, we need to precompute the factors of every number from 1 to 1000000, so that we can get different choices of jumps in O(1) time.
  2. Then, let dp[i] be the minimum jumps required to reach i, we need to find dp[n-1].
  3. So, the recurrence relation becomes:

    dp[i] = min(dp[i], 1 + solve(i+j)), where j is one of the factors of arr[i] & solve() is the recursive function

  4. Find the minimum jumps using this recurrence relation and print it.

Below is the implementation of above approach:

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ code to count minimum factor jumps
// to reach the end of array
  
#include <bits/stdc++.h>
using namespace std;
  
// vector to store factors of each integer
vector<int> factors[100005];
  
// dp array
int dp[100005];
  
// Precomputing all factors of integers
// from 1 to 100000
void precompute()
{
    for (int i = 1; i <= 100000; i++) {
        for (int j = i; j <= 100000; j += i) {
            factors[j].push_back(i);
        }
    }
}
  
// Function to count the minimum jumps
int solve(int arr[], int k, int n)
{
  
    // If we reach the end of array,
    // no more jumps are required
    if (k == n - 1) {
        return 0;
    }
  
    // If the jump results in out of index,
    // return INT_MAX
    if (k >= n) {
        return INT_MAX;
    }
  
    // If the answer has been already computed,
    // return it directly
    if (dp[k]) {
        return dp[k];
    }
  
    // Else compute the answer
    // using the recurrence relation
    int ans = INT_MAX;
  
    // Iterating over all choices of jumps
    for (auto j : factors[arr[k]]) {
  
        // Considering current factor as a jump
        int res = solve(arr, k + j, n);
  
        // Jump leads to the destination
        if (res != INT_MAX) {
            ans = min(ans, res + 1);
        }
    }
  
    // Return ans and memorize it
    return dp[k] = ans;
}
  
// Driver code
int main()
{
  
    // pre-calculating the factors
    precompute();
  
    int arr[] = { 2, 8, 16, 55, 99, 100 };
    int n = sizeof(arr) / sizeof(arr[0]);
  
    cout << solve(arr, 0, n);
}

chevron_right


Output:

2

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.