给定许多硬币,它们是相邻排列的。我们需要以最少的步骤来收集所有这些硬币,其中在一个步骤中,我们可以收集一条水平线的硬币或垂直线的硬币,并且收集的硬币应该是连续的。
例子 :
输入: 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