📌  相关文章
📜  以最少的步骤收集所有硬币

📅  最后修改于: 2021-04-24 21:50:12             🧑  作者: Mango

给定许多硬币,它们是相邻排列的。我们需要以最少的步骤来收集所有这些硬币,其中在一个步骤中,我们可以收集一条水平线的硬币或垂直线的硬币,并且收集的硬币应该是连续的。

例子 :

输入: height [] = [2 1 2 5 1]该数组的每个值对应于堆栈的高度,即我们得到了五叠硬币,其中第一叠有2个硬币,然后在第二叠中有1个硬币等等。输出: 4我们可以分4个步骤收集上述所有硬币,如下图所示。每个步骤均以不同的颜色显示。 首先,我们收集了硬币的最后一条水平线,之后堆叠保持为[1 0 1 4 0],之后,从堆叠3和4收集了另一条水平硬币,然后从堆叠4收集了一条垂直线,最后是水平堆栈1中的行

我们可以使用分而治之的方法解决这个问题。我们可以看到,从下方删除水平线总是有益的。假设我们在递归步骤中处理从l索引到r索引的堆栈,每次我们选择最小高度时,都删除许多水平线,然后将堆栈分成两部分,将l分为最小部分和最小+1直到r和我们将在这些子数组中递归调用。另一件事是我们也可以使用垂直线收集硬币,因此我们将在递归调用和(r – l)的结果之间选择最小值,因为使用(r – l)垂直线我们可以始终收集所有硬币。
每次调用每个子数组并找到其中的最小值时,解决方案的总时间复杂度将为O(N 2 )

C++
// C++ program to find minimum number of
// steps to collect stack of coins
#include 
using namespace std;
  
// recursive method to collect coins from
// height array l to r, with height h already
// collected
int minStepsRecur(int height[], int l, int r, int h)
{
    // if l is more than r, no steps needed
    if (l >= r)
        return 0;
  
    // loop over heights to get minimum height
    // index
    int m = l;
    for (int i = l; i < r; i++)
        if (height[i] < height[m])
            m = i;
  
    /* choose minimum from,
        1) collecting coins using all vertical
        lines (total r - l)
        2) collecting coins using lower horizontal
        lines and recursively on left and right
        segments */
    return min(r - l,
               minStepsRecur(height, l, m, height[m]) + 
               minStepsRecur(height, m + 1, r, height[m]) + 
               height[m] - h);
}
  
// method returns minimum number of step to
// collect coin from stack, with height in
// height[] array
int minSteps(int height[], int N)
{
    return minStepsRecur(height, 0, N, 0);
}
  
// Driver code to test above methods
int main()
{
    int height[] = { 2, 1, 2, 5, 1 };
    int N = sizeof(height) / sizeof(int);
  
    cout << minSteps(height, N) << endl;
    return 0;
}


Java
// Java Code to Collect all coins in
// minimum number of steps
import java.util.*;
  
class GFG {
  
    // recursive method to collect coins from
    // height array l to r, with height h already
    // collected
    public static int minStepsRecur(int height[], int l,
                                           int r, int h)
    {
        // if l is more than r, no steps needed
        if (l >= r)
            return 0;
  
        // loop over heights to get minimum height
        // index
        int m = l;
        for (int i = l; i < r; i++)
            if (height[i] < height[m])
                m = i;
  
        /* choose minimum from,
            1) collecting coins using all vertical
            lines (total r - l)
            2) collecting coins using lower horizontal
            lines and recursively on left and right
            segments */
        return Math.min(r - l,
                        minStepsRecur(height, l, m, height[m]) + 
                        minStepsRecur(height, m + 1, r, height[m]) +
                        height[m] - h);
    }
  
    // method returns minimum number of step to
    // collect coin from stack, with height in
    // height[] array
    public static int minSteps(int height[], int N)
    {
        return minStepsRecur(height, 0, N, 0);
    }
  
    /* Driver program to test above function */
    public static void main(String[] args)
    {
  
        int height[] = { 2, 1, 2, 5, 1 };
        int N = height.length;
  
        System.out.println(minSteps(height, N));
    }
}
  
// This code is contributed by Arnav Kr. Mandal.


Python 3
# Python 3 program to find 
# minimum number of steps 
# to collect stack of coins
  
# recursive method to collect 
# coins from height array l to 
# r, with height h already
# collected
def minStepsRecur(height, l, r, h):
  
    # if l is more than r,
    # no steps needed
    if l >= r:
        return 0;
  
    # loop over heights to 
    # get minimum height index
    m = l
    for i in range(l, r):
        if height[i] < height[m]:
            m = i
  
    # choose minimum from,
    # 1) collecting coins using 
    # all vertical lines (total r - l)
    # 2) collecting coins using 
    # lower horizontal lines and 
    # recursively on left and 
    # right segments 
    return min(r - l,
            minStepsRecur(height, l, m, height[m]) +
            minStepsRecur(height, m + 1, r, height[m]) +
            height[m] - h)
  
# method returns minimum number
# of step to collect coin from 
# stack, with height in height[] array
def minSteps(height, N):
    return minStepsRecur(height, 0, N, 0)
  
# Driver code 
height = [ 2, 1, 2, 5, 1 ]
N = len(height)
print(minSteps(height, N))
  
# This code is contributed
# by ChitraNayal


C#
// C# Code to Collect all coins in
// minimum number of steps
using System;
  
class GFG {
  
    // recursive method to collect coins from
    // height array l to r, with height h already
    // collected
    public static int minStepsRecur(int[] height, int l,
                                           int r, int h)
    {
        // if l is more than r, no steps needed
        if (l >= r)
            return 0;
  
        // loop over heights to
        // get minimum height index
        int m = l;
        for (int i = l; i < r; i++)
            if (height[i] < height[m])
                m = i;
  
        /* choose minimum from,
            1) collecting coins using all vertical
            lines (total r - l)
            2) collecting coins using lower horizontal
            lines and recursively on left and right
            segments */
        return Math.Min(r - l,
                        minStepsRecur(height, l, m, height[m]) + 
                        minStepsRecur(height, m + 1, r, height[m]) +
                        height[m] - h);
    }
  
    // method returns minimum number of step to
    // collect coin from stack, with height in
    // height[] array
    public static int minSteps(int[] height, int N)
    {
        return minStepsRecur(height, 0, N, 0);
    }
  
    /* Driver program to test above function */
    public static void Main()
    {
        int[] height = { 2, 1, 2, 5, 1 };
        int N = height.Length;
  
        Console.Write(minSteps(height, N));
    }
}
  
// This code is contributed by nitin mittal


PHP
= $r)
        return 0;
  
    // loop over heights to
    // get minimum height
    // index
    $m = $l;
    for ($i = $l; $i < $r; $i++)
        if ($height[$i] < $height[$m])
            $m = $i;
  
    /* choose minimum from,
        1) collecting coins using 
           all vertical lines 
           (total r - l)
        2) collecting coins using 
           lower horizontal lines 
           and recursively on left
           and right segments */
    return min($r - $l,
           minStepsRecur($height, $l, $m, $height[$m]) + 
           minStepsRecur($height, $m + 1, $r, $height[$m]) + 
           $height[$m] - $h);
}
  
// method returns minimum number of step to
// collect coin from stack, with height in
// height[] array
function minSteps($height, $N)
{
    return minStepsRecur($height, 0, $N, 0);
}
  
    // Driver Code
    $height = array(2, 1, 2, 5, 1);
    $N = sizeof($height);
  
    echo minSteps($height, $N) ;
      
// This code is contributed by nitin mittal.
?>


输出:

4