📌  相关文章
📜  以长度为 K 的最大跳跃到达数组末尾的最小成本

📅  最后修改于: 2022-05-13 01:56:04.558000             🧑  作者: Mango

以长度为 K 的最大跳跃到达数组末尾的最小成本

给定一个大小为N的数组arr[]和一个整数K ,可以从索引i移动到任何其他索引j ,使得j ≤ i+k 。处于任何索引“ i ”的成本是arr[i] 。任务是找到从索引0开始到达数组末尾最小成本。

例子

天真的方法:可以使用动态规划来解决该任务。维护一个dp[]数组,其中 dp[i] 表示到达第i 个索引所需的最小成本。请按照以下步骤解决问题:

  • 当前元素向后遍历所有K个元素,找到最小dp值并将其添加到当前答案中。
  • 因此,计算第 i 个索引的答案将是dp[i] = arr[i] + min(dp[j]对于所有 j 使得ik <= j < i ) 。

下面是上述方法的实现:

C++
//  C++ program for the above approach
#include 
using namespace std;
 
//  Function to find the minimum jumps
int solve(vector& arr, int K)
{
  int size = arr.size();
  vector dp(size, 0);
 
  //  Initially only a single element
  dp[0] = arr[0];
 
  for (int idx = 1; idx < size; idx++) {
 
    //  At most k elements backwards
    int end = max(-1, idx - K - 1);
    int mini = INT_MAX;
 
    //  Find minimum among all the values
    for (int ptr = idx - 1; ptr > end; ptr--) {
      mini = min(mini, dp[ptr]);
    }
    dp[idx] = arr[idx] + mini;
  }
   
  //  Return cost to reach the
  //  last index of array
  return dp[size - 1];
}
 
//  Driver Code
int main()
{
  vector arr = { 2, 4, 1, 6, 3 };
  int K = 2;
 
  int ans = solve(arr, K);
  cout << ans << "\n";
}
 
// This code is contributed by Taranpreet


Java
// Java program for the above approach
class GFG {
 
  // Function to find the minimum jumps
  static int solve(int[] arr, int K) {
    int size = arr.length;
    int[] dp = new int[size];
 
    for (int i = 0; i < size; i++) {
      dp[i] = 0;
    }
 
    // Initially only a single element
    dp[0] = arr[0];
 
    for (int idx = 1; idx < size; idx++) {
 
      // At most k elements backwards
      int end = Math.max(-1, idx - K - 1);
      int mini = Integer.MAX_VALUE;
 
      // Find minimum among all the values
      for (int ptr = idx - 1; ptr > end; ptr--) {
        mini = Math.min(mini, dp[ptr]);
      }
      dp[idx] = arr[idx] + mini;
    }
 
    // Return cost to reach the
    // last index of array
    return dp[size - 1];
  }
 
  // Driver Code
  public static void main(String args[]) {
    int[] arr = { 2, 4, 1, 6, 3 };
    int K = 2;
 
    int ans = solve(arr, K);
    System.out.println(ans);
  }
}
 
// This code is contributed by Saurabh Jaiswal


Python3
# Python program for the above approach
 
# Function to find the minimum jumps
def solve(arr, K):
    size = len(arr)
    dp = [0] * (size)
 
    # Initially only a single element
    dp[0] = arr[0]
 
    for idx in range(1, size, 1):
 
        # At most k elements backwards
        end = max(-1, idx - K - 1)
        mini = float('inf')
 
        # Find minimum among all the values
        for ptr in range(idx - 1, end, -1):
            mini = min(mini, dp[ptr])
 
        dp[idx] = arr[idx] + mini
 
    # Return cost to reach the
    # last index of array
    return (dp[-1])
 
 
# Driver Code
if __name__ == "__main__":
    arr = [2, 4, 1, 6, 3]
    K = 2
 
    ans = solve(arr, K)
    print(ans)


C#
//  C# program for the above approach
using System;
class GFG
{
   
//  Function to find the minimum jumps
static int solve(int []arr, int K)
{
  int size = arr.Length;
  int []dp = new int[size];
   
  for(int i = 0; i < size; i++) {
    dp[i] = 0;
  }
 
  //  Initially only a single element
  dp[0] = arr[0];
 
  for (int idx = 1; idx < size; idx++) {
 
    //  At most k elements backwards
    int end = Math.Max(-1, idx - K - 1);
    int mini = Int32.MaxValue;
 
    //  Find minimum among all the values
    for (int ptr = idx - 1; ptr > end; ptr--) {
      mini = Math.Min(mini, dp[ptr]);
    }
    dp[idx] = arr[idx] + mini;
  }
   
  //  Return cost to reach the
  //  last index of array
  return dp[size - 1];
}
 
//  Driver Code
public static void Main()
{
  int []arr = { 2, 4, 1, 6, 3 };
  int K = 2;
 
  int ans = solve(arr, K);
  Console.WriteLine(ans);
}
}
 
// This code is contributed by Samim Hossain Mondal.


Javascript


C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to find the minimum jumps
int solve(int arr[], int K, int size)
{
  deque > ququ;
 
  // Insert index and value
  ququ.push_back({ 0, arr[0] });
 
  for (int i = 1; i < size; i++) {
    // Remove elements from front
    // which are out of curr_window size
    while ((ququ.size() > 0)
           && ((i - ququ.front().first) > K))
      ququ.pop_front();
 
    int curr_val = arr[i] + ququ.front().second;
 
    // Pop greater elements from back
    while ((ququ.size() > 0)
           && (curr_val <= ququ.back().second))
      ququ.pop_back();
 
    // Append index and curr_val
    ququ.push_back({ i, curr_val });
  }
 
  // Finally return last value
  // indicating cost to reach the last index
  return ququ.back().second;
}
 
// driver code
int main()
{
  int arr[] = { 2, 4, 1, 6, 3 };
  int K = 2;
  int size = sizeof(arr) / sizeof(arr[0]);
 
  int ans = solve(arr, K, size);
  cout << ans << endl;
  return 0;
}
 
// This code is contributed by Palak Gupta


Python3
# Python program for the above approach
from collections import deque
 
# Function to find the minimum jumps
def solve(arr, K):
    size = len(arr)
    ququ = deque()
 
    # Insert index and value
    ququ.append((0, arr[0]))
 
    for i in range(1, size, 1):
 
        # Remove elements from front
        # which are out of curr_window size
        while(ququ and i - ququ[0][0] > K):
            ququ.popleft()
 
        curr_val = arr[i] + ququ[0][1]
 
        # Pop greater elements from back
        while(ququ and curr_val <= ququ[-1][1]):
            ququ.pop()
 
        # Append index and curr_val
        ququ.append((i, curr_val))
 
    # Finally return last value
    # indicating cost to reach the last index
    return ququ[-1][1]
 
 
# Driver Code
if __name__ == "__main__":
    arr = [2, 4, 1, 6, 3]
    K = 2
 
    ans = solve(arr, K)
    print(ans)


输出:
6

时间复杂度:O(N * K)
辅助空间:O(N)

高效方法:不是计算每个索引最小成本,而是使用滑动窗口方法。使用大小为K的滑动窗口,使得最小元素始终出现在前面并保持排序顺序。请按照以下步骤解决问题:

  • 初始化双端队列以保存数据,因为它支持从正面和背面弹出元素的高效操作。
  • 在双端队列中插入第一个元素及其索引。还会插入索引以跟踪是否有任何元素在大小K的窗口限制内。
  • 然后,从索引 1 开始循环直到数组的末尾。对于每个索引,从前面删除所有超出当前窗口大小的元素,即索引之间的差异> k。
  • current_value计算为arr[i]dequeue 的第一个值的总和。这里添加了第一个值,因为它是当前窗口中的最小值。
  • 然后从 deque 中弹出所有值大于或等于 current_value 的元素。这样做是为了维护双端队列中的排序顺序。
  • 最后返回双端队列中的最后一个值,显示到达数组最后一个索引的成本。

下面是上述方法的实现:

C++

// C++ program for the above approach
#include 
using namespace std;
 
// Function to find the minimum jumps
int solve(int arr[], int K, int size)
{
  deque > ququ;
 
  // Insert index and value
  ququ.push_back({ 0, arr[0] });
 
  for (int i = 1; i < size; i++) {
    // Remove elements from front
    // which are out of curr_window size
    while ((ququ.size() > 0)
           && ((i - ququ.front().first) > K))
      ququ.pop_front();
 
    int curr_val = arr[i] + ququ.front().second;
 
    // Pop greater elements from back
    while ((ququ.size() > 0)
           && (curr_val <= ququ.back().second))
      ququ.pop_back();
 
    // Append index and curr_val
    ququ.push_back({ i, curr_val });
  }
 
  // Finally return last value
  // indicating cost to reach the last index
  return ququ.back().second;
}
 
// driver code
int main()
{
  int arr[] = { 2, 4, 1, 6, 3 };
  int K = 2;
  int size = sizeof(arr) / sizeof(arr[0]);
 
  int ans = solve(arr, K, size);
  cout << ans << endl;
  return 0;
}
 
// This code is contributed by Palak Gupta

Python3

# Python program for the above approach
from collections import deque
 
# Function to find the minimum jumps
def solve(arr, K):
    size = len(arr)
    ququ = deque()
 
    # Insert index and value
    ququ.append((0, arr[0]))
 
    for i in range(1, size, 1):
 
        # Remove elements from front
        # which are out of curr_window size
        while(ququ and i - ququ[0][0] > K):
            ququ.popleft()
 
        curr_val = arr[i] + ququ[0][1]
 
        # Pop greater elements from back
        while(ququ and curr_val <= ququ[-1][1]):
            ququ.pop()
 
        # Append index and curr_val
        ququ.append((i, curr_val))
 
    # Finally return last value
    # indicating cost to reach the last index
    return ququ[-1][1]
 
 
# Driver Code
if __name__ == "__main__":
    arr = [2, 4, 1, 6, 3]
    K = 2
 
    ans = solve(arr, K)
    print(ans)
输出
6

时间复杂度:O(N)
辅助空间:O(N)