给定许多相邻排列的硬币堆。我们需要以最少的步骤收集所有这些硬币,其中一步我们可以收集一个水平线或垂直线的硬币,并且收集的硬币应该是连续的。
例子 :
Input : height[] = [2 1 2 5 1]
Each value of this array corresponds to
the height of stack that is we are given
five stack of coins, where in first stack
2 coins are there then in second stack
1 coin is there and so on.
Output : 4
We can collect all above coins in 4 steps
which are shown in below diagram.
Each step is shown by different color.
First, we have collected last horizontal
line of coins after which stacks remains
as [1 0 1 4 0] after that, another horizontal
line of coins is collected from stack 3
and 4 then a vertical line from stack 4
and at the end a horizontal line from
stack 1. Total steps are 4.
我们可以使用分治法来解决这个问题。我们可以看到从下面去除水平线总是有益的。假设我们在递归步骤中处理从 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.
?>
Javascript
输出:
4
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。