📌  相关文章
📜  计算到达数组末尾所需的最小因子跳转

📅  最后修改于: 2021-04-24 14:52:16             🧑  作者: Mango

给定正整数数组arr [] ,任务是计算到达数组末尾所需的最小因子跳跃。从任何特定的索引i出发,仅可以对K个索引(其中Karr [i]的因子)进行跳转。

例子:

方法:可以使用动态编程解决此问题。

  • 首先,我们需要预先计算每个数字从1到1000000的因数,以便我们可以在O(1)时间中获得不同的跳跃选择。
  • 然后,让dp [i]是达到i所需的最小跳跃,我们需要找到dp [n-1]
  • 因此,递归关系变为:
  • 使用此重复关系找到最小跳跃并打印。

下面是上述方法的递归实现:

C++
// C++ code to count minimum factor jumps
// to reach the end of array
 
#include 
using namespace std;
 
// vector to store factors of each integer
vector 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);
}


Java
// Java code to count minimum
// factor jumps to reach the
// end of array
import java.util.*;
class GFG{
 
// vector to store factors
// of each integer
static Vector []factors =
              new Vector[100005];
 
// dp array
static int []dp = new int[100005];
 
// Precomputing all factors
// of integers from 1 to 100000
static void precompute()
{
  for (int i = 0; i < factors.length; i++)
    factors[i] = new Vector();
  for (int i = 1; i <= 100000; i++)
  {
    for (int j = i; j <= 100000; j += i)
    {
      factors[j].add(i);
    }
  }
}
 
// Function to count the
// minimum jumps
static 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
  // Integer.MAX_VALUE
  if (k >= n)
  {
    return Integer.MAX_VALUE;
  }
 
  // If the answer has been
  // already computed, return
  // it directly
  if (dp[k] != 0)
  {
    return dp[k];
  }
 
  // Else compute the answer
  // using the recurrence relation
  int ans = Integer.MAX_VALUE;
 
  // Iterating over all choices
  // of jumps
  for (int j : factors[arr[k]])
  {
    // Considering current factor
    // as a jump
    int res = solve(arr, k + j, n);
 
    // Jump leads to the destination
    if (res != Integer.MAX_VALUE)
    {
      ans = Math.min(ans, res + 1);
    }
  }
 
  // Return ans and memorize it
  return dp[k] = ans;
}
 
// Driver code
public static void main(String[] args)
{
  // pre-calculating
  // the factors
  precompute();
 
  int arr[] = {2, 8, 16,
               55, 99, 100};
  int n = arr.length;
  System.out.print(solve(arr, 0, n));
}
}
 
// This code is contributed by Rajput-Ji


Python3
# Python3 code to count minimum factor jumps
# to reach the end of array
  
# vector to store factors of each integer
factors= [[] for i in range(100005)];
  
# dp array
dp = [0 for i in range(100005)];
  
# Precomputing all factors of integers
# from 1 to 100000
def precompute():
 
    for i in range(1, 100001):
        for j in range(i, 100001, i):
     
            factors[j].append(i);
  
# Function to count the minimum jumps
def solve(arr, k, 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 1000000000
     
    # If the answer has been already computed,
    # return it directly
    if (dp[k]):
        return dp[k];
     
    # Else compute the answer
    # using the recurrence relation
    ans = 1000000000
  
    # Iterating over all choices of jumps
    for j in factors[arr[k]]:
  
        # Considering current factor as a jump
        res = solve(arr, k + j, n);
  
        # Jump leads to the destination
        if (res != 1000000000):
            ans = min(ans, res + 1);
         
    # Return ans and memorize it
    dp[k] = ans;
    return ans
 
# Driver code
if __name__=='__main__':
  
    # pre-calculating the factors
    precompute()
  
    arr = [ 2, 8, 16, 55, 99, 100 ]
    n = len(arr)
     
    print(solve(arr, 0, n))
  
# This code is contributed by rutvik_56


C#
// C# code to count minimum
// factor jumps to reach the
// end of array
using System;
using System.Collections.Generic;
class GFG{
 
// vector to store factors
// of each integer
static List []factors =
            new List[100005];
 
// dp array
static int []dp = new int[100005];
 
// Precomputing all factors
// of integers from 1 to 100000
static void precompute()
{
  for (int i = 0;
           i < factors.Length; i++)
    factors[i] = new List();
  for (int i = 1; i <= 100000; i++)
  {
    for (int j = i;
             j <= 100000; j += i)
    {
      factors[j].Add(i);
    }
  }
}
 
// Function to count the
// minimum jumps
static 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.MaxValue
  if (k >= n)
  {
    return int.MaxValue;
  }
 
  // If the answer has been
  // already computed, return
  // it directly
  if (dp[k] != 0)
  {
    return dp[k];
  }
 
  // Else compute the answer
  // using the recurrence relation
  int ans = int.MaxValue;
 
  // Iterating over all choices
  // of jumps
  foreach (int j in factors[arr[k]])
  {
    // Considering current 
    // factor as a jump
    int res = solve(arr, k + j, n);
 
    // Jump leads to the
    // destination
    if (res != int.MaxValue)
    {
      ans = Math.Min(ans, res + 1);
    }
  }
 
  // Return ans and
  // memorize it
  return dp[k] = ans;
}
 
// Driver code
public static void Main(String[] args)
{
  // pre-calculating
  // the factors
  precompute();
 
  int []arr = {2, 8, 16,
               55, 99, 100};
  int n = arr.Length;
  Console.Write(solve(arr, 0, n));
}
}
 
// This code is contributed by shikhasingrajput


C++
// C++ program for bottom up approach
#include 
using namespace std;
 
// Vector to store factors of each integer
vector factors[100005];
 
// Initialize the dp array
int dp[100005];
 
// Precompute all the
// factors of every integer
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 factor jump
int solve(int arr[], int n)
{
 
    // Initialise minimum jumps to
    // reach each cell as INT_MAX
    for (int i = 0; i <= 100005; i++) {
        dp[i] = INT_MAX;
    }
 
    // 0 jumps required to
    // reach the first cell
    dp[0] = 0;
 
    // Iterate over all cells
    for (int i = 0; i < n; i++) {
        // calculating for each jump
        for (auto j : factors[arr[i]]) {
            // If a cell is in bound
            if (i + j < n)
                dp[i + j] = min(dp[i + j], 1 + dp[i]);
        }
    }
    // Return minimum jumps
    // to reach last cell
    return dp[n - 1];
}
 
// Driver code
int main()
{
    // Pre-calculating the factors
    precompute();
    int arr[] = { 2, 8, 16, 55, 99, 100 };
    int n = sizeof(arr) / sizeof(arr[0]);
 
    // Function call
    cout << solve(arr, n);
}


Java
// Java program for bottom up approach
import java.util.*;
 
class GFG{
 
// Vector to store factors of each integer
@SuppressWarnings("unchecked")
static Vector []factors = new Vector[100005];
 
// Initialize the dp array
static int []dp = new int[100005];
 
// Precompute all the
// factors of every integer
static void precompute()
{
    for(int i = 1; i <= 100000; i++)
    {
        for(int j = i; j <= 100000; j += i)
            factors[j].add(i);
    }
}
 
// Function to count the
// minimum factor jump
static int solve(int arr[], int n)
{
     
    // Initialise minimum jumps to
    // reach each cell as Integer.MAX_VALUE
    for(int i = 0; i < 100005; i++)
    {
        dp[i] = Integer.MAX_VALUE;
    }
 
    // 0 jumps required to
    // reach the first cell
    dp[0] = 0;
 
    // Iterate over all cells
    for(int i = 0; i < n; i++)
    {
         
        // Calculating for each jump
        for(int j : factors[arr[i]])
        {
             
            // If a cell is in bound
            if (i + j < n)
                dp[i + j] = Math.min(dp[i + j],
                                        1 + dp[i]);
        }
    }
     
    // Return minimum jumps
    // to reach last cell
    return dp[n - 1];
}
 
// Driver code
public static void main(String[] args)
{
    for(int i = 0; i < factors.length; i++)
        factors[i] = new Vector();
         
    // Pre-calculating the factors
    precompute();
    int arr[] = { 2, 8, 16, 55, 99, 100 };
    int n = arr.length;
 
    // Function call
    System.out.print(solve(arr, n));
}
}
 
// This code is contributed by Princi Singh


Python3
# Python3 program for bottom up approach
  
# Vector to store factors of each integer
factors=[[] for i in range(100005)];
  
# Initialize the dp array
dp=[1000000000 for i in range(100005)];
  
# Precompute all the
# factors of every integer
def precompute():
     
    for i in range(1, 100001):
         
        for j in range(i, 100001, i):
     
            factors[j].append(i);
      
# Function to count the
# minimum factor jump
def solve(arr, n):
   
    # 0 jumps required to
    # reach the first cell
    dp[0] = 0;
  
    # Iterate over all cells
    for i in range(n):
     
        # calculating for each jump
        for j in factors[arr[i]]:
         
            # If a cell is in bound
            if (i + j < n):
                dp[i + j] = min(dp[i + j], 1 + dp[i]);
         
    # Return minimum jumps
    # to reach last cell
    return dp[n - 1];
  
# Driver code
if __name__=='__main__':
     
    # Pre-calculating the factors
    precompute();
    arr = [ 2, 8, 16, 55, 99, 100 ]
    n=len(arr)
  
    # Function call
    print(solve(arr,n))
     
    # This code is contributed by pratham76


C#
// C# program for bottom up approach
using System;
using System.Collections.Generic;
 
class GFG{
     
// Vector to store factors of each integer
static List> factors = new List>();
 
// Initialize the dp array
static int[] dp;
 
// Precompute all the
// factors of every integer
static void precompute()
{
    for(int i = 1; i <= 100000; i++)
    {
        for(int j = i; j <= 100000; j += i)
            factors[j].Add(i);
    }
}
 
// Function to count the
// minimum factor jump
static int solve(int[] arr, int n)
{
     
    // Initialise minimum jumps to
    // reach each cell as Integer.MAX_VALUE
    for(int i = 0; i < 100005; i++)
    {
        dp[i] = int.MaxValue;
    }
 
    // 0 jumps required to
    // reach the first cell
    dp[0] = 0;
 
    // Iterate over all cells
    for(int i = 0; i < n; i++)
    {
         
        // Calculating for each jump
        foreach(int j in factors[arr[i]])
        {
             
            // If a cell is in bound
            if (i + j < n)
                dp[i + j] = Math.Min(dp[i + j],
                                        1 + dp[i]);
        }
    }
     
    // Return minimum jumps
    // to reach last cell
    return dp[n - 1];
}
 
// Driver code
static public void Main ()
{
    for(int i = 0; i < 100005; i++)
        factors.Add(new List());
     
    dp = new int[100005];
     
    // Pre-calculating the factors
    precompute();
    int[] arr = { 2, 8, 16, 55, 99, 100 };
    int n = arr.Length;
     
    // Function call
    Console.Write(solve(arr, n));
}
}
 
// This code is contributed by offbeat


输出
2

下面给出了自下而上的迭代方法:

C++

// C++ program for bottom up approach
#include 
using namespace std;
 
// Vector to store factors of each integer
vector factors[100005];
 
// Initialize the dp array
int dp[100005];
 
// Precompute all the
// factors of every integer
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 factor jump
int solve(int arr[], int n)
{
 
    // Initialise minimum jumps to
    // reach each cell as INT_MAX
    for (int i = 0; i <= 100005; i++) {
        dp[i] = INT_MAX;
    }
 
    // 0 jumps required to
    // reach the first cell
    dp[0] = 0;
 
    // Iterate over all cells
    for (int i = 0; i < n; i++) {
        // calculating for each jump
        for (auto j : factors[arr[i]]) {
            // If a cell is in bound
            if (i + j < n)
                dp[i + j] = min(dp[i + j], 1 + dp[i]);
        }
    }
    // Return minimum jumps
    // to reach last cell
    return dp[n - 1];
}
 
// Driver code
int main()
{
    // Pre-calculating the factors
    precompute();
    int arr[] = { 2, 8, 16, 55, 99, 100 };
    int n = sizeof(arr) / sizeof(arr[0]);
 
    // Function call
    cout << solve(arr, n);
}

Java

// Java program for bottom up approach
import java.util.*;
 
class GFG{
 
// Vector to store factors of each integer
@SuppressWarnings("unchecked")
static Vector []factors = new Vector[100005];
 
// Initialize the dp array
static int []dp = new int[100005];
 
// Precompute all the
// factors of every integer
static void precompute()
{
    for(int i = 1; i <= 100000; i++)
    {
        for(int j = i; j <= 100000; j += i)
            factors[j].add(i);
    }
}
 
// Function to count the
// minimum factor jump
static int solve(int arr[], int n)
{
     
    // Initialise minimum jumps to
    // reach each cell as Integer.MAX_VALUE
    for(int i = 0; i < 100005; i++)
    {
        dp[i] = Integer.MAX_VALUE;
    }
 
    // 0 jumps required to
    // reach the first cell
    dp[0] = 0;
 
    // Iterate over all cells
    for(int i = 0; i < n; i++)
    {
         
        // Calculating for each jump
        for(int j : factors[arr[i]])
        {
             
            // If a cell is in bound
            if (i + j < n)
                dp[i + j] = Math.min(dp[i + j],
                                        1 + dp[i]);
        }
    }
     
    // Return minimum jumps
    // to reach last cell
    return dp[n - 1];
}
 
// Driver code
public static void main(String[] args)
{
    for(int i = 0; i < factors.length; i++)
        factors[i] = new Vector();
         
    // Pre-calculating the factors
    precompute();
    int arr[] = { 2, 8, 16, 55, 99, 100 };
    int n = arr.length;
 
    // Function call
    System.out.print(solve(arr, n));
}
}
 
// This code is contributed by Princi Singh

Python3

# Python3 program for bottom up approach
  
# Vector to store factors of each integer
factors=[[] for i in range(100005)];
  
# Initialize the dp array
dp=[1000000000 for i in range(100005)];
  
# Precompute all the
# factors of every integer
def precompute():
     
    for i in range(1, 100001):
         
        for j in range(i, 100001, i):
     
            factors[j].append(i);
      
# Function to count the
# minimum factor jump
def solve(arr, n):
   
    # 0 jumps required to
    # reach the first cell
    dp[0] = 0;
  
    # Iterate over all cells
    for i in range(n):
     
        # calculating for each jump
        for j in factors[arr[i]]:
         
            # If a cell is in bound
            if (i + j < n):
                dp[i + j] = min(dp[i + j], 1 + dp[i]);
         
    # Return minimum jumps
    # to reach last cell
    return dp[n - 1];
  
# Driver code
if __name__=='__main__':
     
    # Pre-calculating the factors
    precompute();
    arr = [ 2, 8, 16, 55, 99, 100 ]
    n=len(arr)
  
    # Function call
    print(solve(arr,n))
     
    # This code is contributed by pratham76

C#

// C# program for bottom up approach
using System;
using System.Collections.Generic;
 
class GFG{
     
// Vector to store factors of each integer
static List> factors = new List>();
 
// Initialize the dp array
static int[] dp;
 
// Precompute all the
// factors of every integer
static void precompute()
{
    for(int i = 1; i <= 100000; i++)
    {
        for(int j = i; j <= 100000; j += i)
            factors[j].Add(i);
    }
}
 
// Function to count the
// minimum factor jump
static int solve(int[] arr, int n)
{
     
    // Initialise minimum jumps to
    // reach each cell as Integer.MAX_VALUE
    for(int i = 0; i < 100005; i++)
    {
        dp[i] = int.MaxValue;
    }
 
    // 0 jumps required to
    // reach the first cell
    dp[0] = 0;
 
    // Iterate over all cells
    for(int i = 0; i < n; i++)
    {
         
        // Calculating for each jump
        foreach(int j in factors[arr[i]])
        {
             
            // If a cell is in bound
            if (i + j < n)
                dp[i + j] = Math.Min(dp[i + j],
                                        1 + dp[i]);
        }
    }
     
    // Return minimum jumps
    // to reach last cell
    return dp[n - 1];
}
 
// Driver code
static public void Main ()
{
    for(int i = 0; i < 100005; i++)
        factors.Add(new List());
     
    dp = new int[100005];
     
    // Pre-calculating the factors
    precompute();
    int[] arr = { 2, 8, 16, 55, 99, 100 };
    int n = arr.Length;
     
    // Function call
    Console.Write(solve(arr, n));
}
}
 
// This code is contributed by offbeat
输出
2