📌  相关文章
📜  最小化到达阵列末端所需的步骤数

📅  最后修改于: 2021-04-29 18:36:49             🧑  作者: Mango

给定长度N的正整数组成的整数数组arr [],任务是使达到索引“ N-1”所需的步数最小化。在给定的步骤中,如果我们位于索引“ i”,则可以进入索引“ i-arr [i]”或“ i + arr [i]”,因为我们之前没有访问过这些索引。同样,我们不能超出数组的范围。如果没有办法,请打印-1。

例子:

Input : arr[] = {1, 1, 1}
Output : 2
The path will be 0 -> 1 -> 2.
Step 1 - 0 to 1
Step 2 - 1 to 2

Input : {2, 1}
Output : -1

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

让我们讨论一种在开始时似乎正确的方法。假设我们处于i索引。我们可以直接说dp [i] = 1 + min(dp [i-arr [i]],dp [i + arr [i]])吗?

不,我们不可以。我们达到索引“ i”的路径也很重要,因为以前使用的索引将无法再访问。

因此,剩下的唯一方法就是尝试所有可能很大的组合。在本文中,我们将使用位屏蔽方法将复杂度降低到指数级。我们的掩码将是具有以下功能的整数值。

1) If, a index 'i' is visited, ith bit 
   will be set 1 in the mask. 
2) Else that bit will be set 0.

所需的递归关系将是。

dp[i][mask] = 1 + min(dp[i+arr[i]][mask|(1<

下面是上述方法的实现:

CPP
// C++ implementation of the above approach
  
#include 
#define maxLen 10
#define maskLen 130
using namespace std;
  
// variable to store states of dp
int dp[maxLen][maskLen];
  
// variable to check if a given state
// has been solved
bool v[maxLen][maskLen];
  
// Function to find the minimum number of steps 
// required to reach the end of the array
int minSteps(int arr[], int i, int mask, int n)
{
    // base case
    if (i == n - 1)
        return 0;
  
    if (i > n - 1 || i < 0)
        return 9999999;
    if ((mask >> i) & 1)
        return 9999999;
  
    // to check if a state has
    // been solved
    if (v[i][mask])
        return dp[i][mask];
    v[i][mask] = 1;
  
    // required recurrence relation
    dp[i][mask] = 1 + min(minSteps(arr, i - arr[i], (mask | (1 << i)), n), 
                          minSteps(arr, i + arr[i], (mask | (1 << i)), n));
  
    // returning the value
    return dp[i][mask];
}
  
// Driver code
int main()
{
    int arr[] = { 1, 2, 2, 2, 1, 1 };
  
    int n = sizeof(arr) / sizeof(int);
  
    int ans = minSteps(arr, 0, 0, n);
    if (ans >= 9999999)
        cout << -1;
    else
        cout << ans;
}


Java
// Java implementation of the above approach
  
class GFG
{
  
    static int maxLen = 10;
    static int maskLen = 130;
  
    // variable to store states of dp
    static int[][] dp = new int[maxLen][maskLen];
  
    // variable to check if a given state
    // has been solved
    static boolean[][] v = new boolean[maxLen][maskLen];
  
    // Function to find the minimum number of steps 
    // required to reach the end of the array
    static int minSteps(int arr[], int i, int mask, int n) 
    {
        // base case
        if (i == n - 1)
        {
            return 0;
        }
  
        if (i > n - 1 || i < 0) 
        {
            return 9999999;
        }
        if ((mask >> i) % 2 == 1) 
        {
            return 9999999;
        }
  
        // to check if a state has
        // been solved
        if (v[i][mask])
        {
            return dp[i][mask];
        }
        v[i][mask] = true;
  
        // required recurrence relation
        dp[i][mask] = 1 + Math.min(minSteps(arr, i - arr[i], (mask | (1 << i)), n),
                                minSteps(arr, i + arr[i], (mask | (1 << i)), n));
  
        // returning the value
        return dp[i][mask];
    }
  
    // Driver code
    public static void main(String[] args) 
    {
        int arr[] = {1, 2, 2, 2, 1, 1};
  
        int n = arr.length;
  
        int ans = minSteps(arr, 0, 0, n);
        if (ans >= 9999999) 
        {
            System.out.println(-1);
        }
        else
        {
            System.out.println(ans);
        }
    }
}
  
/* This code contributed by PrinciRaj1992 */


Python
# Python3 implementation of the above approach
maxLen = 10
maskLen = 130
  
  
# variable to store states of dp
dp = [[ 0 for i in range(maskLen)] for i in range(maxLen)]
  
# variable to check if a given state
# has been solved
v = [[False for i in range(maskLen)] for i in range(maxLen)]
  
# Function to find the minimum number of steps 
# required to reach the end of the array
def minSteps(arr, i, mask, n):
  
    # base case
    if (i == n - 1):
        return 0
  
    if (i > n - 1 or i < 0):
        return 9999999
  
    if ((mask >> i) & 1):
        return 9999999
  
    # to check if a state has
    # been solved
    if (v[i][mask] == True):
        return dp[i][mask]
    v[i][mask] = True
  
    # required recurrence relation
    dp[i][mask] = 1 + min(minSteps(arr, i - arr[i], (mask | (1 << i)), n), 
                        minSteps(arr, i + arr[i], (mask | (1 << i)), n))
  
    # returning the value
    return dp[i][mask]
  
  
# Driver code
  
arr=[1, 2, 2, 2, 1, 1]
  
n = len(arr)
  
ans = minSteps(arr, 0, 0, n)
  
if (ans >= 9999999):
    print(-1)
else:
    print(ans)
      
# This code is contributed by mohit kumar 29


C#
// C# implementation of the above approach
using System;
  
class GFG
{
      
    static int maxLen = 10;
    static int maskLen = 130;
  
    // variable to store states of dp
    static int[,] dp = new int[maxLen, maskLen];
  
    // variable to check if a given state
    // has been solved
    static bool[,] v = new bool[maxLen, maskLen];
  
    // Function to find the minimum number of steps 
    // required to reach the end of the array
    static int minSteps(int []arr, int i, int mask, int n) 
    {
        // base case
        if (i == n - 1)
        {
            return 0;
        }
  
        if (i > n - 1 || i < 0) 
        {
            return 9999999;
        }
        if ((mask >> i) % 2 == 1) 
        {
            return 9999999;
        }
  
        // to check if a state has
        // been solved
        if (v[i, mask])
        {
            return dp[i, mask];
        }
        v[i, mask] = true;
  
        // required recurrence relation
        dp[i,mask] = 1 + Math.Min(minSteps(arr, i - arr[i], (mask | (1 << i)), n),
                                minSteps(arr, i + arr[i], (mask | (1 << i)), n));
  
        // returning the value
        return dp[i,mask];
    }
  
    // Driver code
    static public void Main ()
    {
        int []arr = {1, 2, 2, 2, 1, 1};
  
        int n = arr.Length;
  
        int ans = minSteps(arr, 0, 0, n);
        if (ans >= 9999999) 
        {
            Console.WriteLine(-1);
        }
        else
        {
            Console.WriteLine(ans);
        }
    }
}
  
/* This code contributed by ajit. */


输出:
3

时间复杂度:O(N *(2 N ))