给定一个正整数数组arr[] ,任务是计算到达数组末尾所需的最小因子跳跃。从任何特定索引i ,只能对K 个索引进行跳转,其中K是arr[i] 的一个因子。
例子:
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, they jumped 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
方法:这个问题可以用动态规划解决。
- 首先,我们需要预先计算从1到1000000的每个数的因数,这样我们就可以在O(1)时间内得到不同的跳跃选择。
- 然后,让dp[i]是到达 i 所需的最小跳跃,我们需要找到dp[n-1] 。
- 因此,递推关系变为:
where j is one of the factors of arr[i] & solve() is the recursive function
- 使用此递推关系找到最小跳跃并打印它。
下面是上述方法的递归实现:
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
Javascript
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
Javascript
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
蟒蛇3
# 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
Javascript
2
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。