根据给定规则删除数组的所有元素所需的最小硬币数
给定一个长度为N的数组arr ,其值 1 和 2 表示类型 1 和类型 2 元素以及两个玩家 player1 和 player2。任务是找到按照数组中给定的顺序删除所有元素所需的最小硬币数。必须遵守以下规则:
- Player1 和 Player2 轮流删除 Player1 先开始的元素
- 两者都可以删除最多 2 个相邻元素,并且必须轮流删除至少一个元素
- Type 2 元素可以被他们两个都移除而不需要硬币
- 类型 1 元素可以被 Player2 移除而无需硬币,但 Player1 将需要硬币来移除元素
例子:
Input: N = 8 arr = [1, 2, 1, 1, 2, 1, 1, 1]
Output: 2
Explanation: Total coins needed by Player1 is 2. Below are the elements removed at each player’s turn:
- Player1 will remove the first element of type 1 using one coin and second element of type 2 without a coin
- Player2 will remove the next two elements
- Player1 will start its operation and remove only the next element of type 2 without a coin
- Player2 will start its operation and remove next two elements at index 5 and 6 in the array
- Player1 will remove the last element of type 1 using one coin
Input: N = 4 arr = [1, 1, 2, 2]
Output: 2
Explanation: Total coins needed by Player1 is 1. Below are the elements removed at each player’s turn
- Player1 will remove the first element of type 1 using one coin
- Player2 will remove the 2nd and the 3rd element
- Player1 will remove the 4th element of type 2 without a coin
方法:给定的问题可以用两个指针的贪心方法来解决。可以按照以下步骤解决问题:
- 第一个元素单独考虑。如果它是 1 类型,那么 1 将被添加到需要移除元素的总硬币中
- 考虑轮到 Player1 从第二个索引迭代数组
- 如果轮到 Player1 并且第一个元素是类型 2 并且下一个元素是类型 1 则 Player1 将仅删除类型 2 的元素,然后 Player2 可以开始操作
- 如果轮到 Player1 并且两个连续的类型为 2 的元素,那么在该操作中,Player1 将删除这两个元素
- 如果轮到玩家 1 并且有 3 个连续的类型 1 的元素,那么玩家 1 将只使用一个硬币移除第一个元素,接下来的两个元素可以被玩家 2 移除
- 考虑到上述三种情况,可以观察到每个类型 1 元素的块都以 Player2 的操作开始
- 因此对于类型 1 的每三个连续元素,可以看出 Player1 需要一个硬币来移除一个元素,而 Player2 将移除两个元素
C++
// C++ implementation for the above approach
#include
using namespace std;
// Function to calculate minimum
// number of coins needed
int minimumcoins(int arr[], int N)
{
int coins = 0;
int j = 0;
// Consider the first element
// separately, add 1 to the total
// if it's of type 1
if (arr[0] == 1)
coins++;
// Iterate from the second element
for (int i = 1; i < N; i++) {
// If the current element is
// of type 2 then any Player
// can remove the element
if (arr[i] == 2)
continue;
// Second pointer to reach end of
// type 1 elements
j = i;
// Increment j until arr[j]
// is equal to 1 and j is not
// out of bounds
while (j < N && arr[j] == 1) {
j++;
}
// Number of type 1 elements
// in a continuous chunk
int x = (j - i);
coins += x / 3;
// From next iteration i
// pointer will start from
// index of j
i = j - 1;
}
// Return the minimum count of coins
return coins;
}
int main()
{
int N = 8;
int arr[] = { 1, 2, 1, 1, 2, 1, 1, 1 };
cout << minimumcoins(arr, N);
return 0;
}
Java
// Java implementation for the above approach
import java.io.*;
import java.util.*;
class GFG {
// Function to calculate minimum
// number of coins needed
static int minimumcoins(int arr[], int N)
{
int coins = 0;
int j = 0;
// Consider the first element
// separately, add 1 to the total
// if it's of type 1
if (arr[0] == 1)
coins++;
// Iterate from the second element
for (int i = 1; i < N; i++) {
// If the current element is
// of type 2 then any Player
// can remove the element
if (arr[i] == 2)
continue;
// Second pointer to reach end of
// type 1 elements
j = i;
// Increment j until arr[j]
// is equal to 1 and j is not
// out of bounds
while (j < N && arr[j] == 1) {
j++;
}
// Number of type 1 elements
// in a continuous chunk
int x = (j - i);
coins += x / 3;
// From next iteration i
// pointer will start from
// index of j
i = j - 1;
}
// Return the minimum count of coins
return coins;
}
// Driver Code
public static void main(String[] args)
{
int N = 8;
int arr[] = { 1, 2, 1, 1, 2, 1, 1, 1 };
// Function Call
System.out.println(minimumcoins(arr, N));
}
}
// This code is contributed by dwivediyash
Python3
# Python program for the above approach
# Function to calculate minimum
# number of coins needed
def minimumcoins(arr, N) :
coins = 0
j = 0
# Consider the first element
# separately, add 1 to the total
# if it's of type 1
if (arr[0] == 1) :
coins += 1
# Iterate from the second element
for i in range(1, N) :
# If the current element is
# of type 2 then any Player
# can remove the element
if (arr[i] == 2) :
continue
# Second pointer to reach end of
# type 1 elements
j = i
# Increment j until arr[j]
# is equal to 1 and j is not
# out of bounds
while (j < N and arr[j] == 1) :
j += 1
# Number of type 1 elements
# in a continuous chunk
x = (j - i)
coins += x // 3
# From next iteration i
# pointer will start from
# index of j
i = j - 1
# Return the minimum count of coins
return coins
# Driver Code
N = 8
arr = [ 1, 2, 1, 1, 2, 1, 1, 1 ]
print(minimumcoins(arr, N))
# This code is contributed by sanjoy_62.
C#
// C# implementation for the above approach
using System;
public class GFG {
// Function to calculate minimum
// number of coins needed
static int minimumcoins(int []arr, int N)
{
int coins = 0;
int j = 0;
// Consider the first element
// separately, add 1 to the total
// if it's of type 1
if (arr[0] == 1)
coins++;
// Iterate from the second element
for (int i = 1; i < N; i++) {
// If the current element is
// of type 2 then any Player
// can remove the element
if (arr[i] == 2)
continue;
// Second pointer to reach end of
// type 1 elements
j = i;
// Increment j until arr[j]
// is equal to 1 and j is not
// out of bounds
while (j < N && arr[j] == 1) {
j++;
}
// Number of type 1 elements
// in a continuous chunk
int x = (j - i);
coins += x / 3;
// From next iteration i
// pointer will start from
// index of j
i = j - 1;
}
// Return the minimum count of coins
return coins;
}
// Driver Code
public static void Main(String[] args)
{
int N = 8;
int []arr = { 1, 2, 1, 1, 2, 1, 1, 1 };
// Function Call
Console.WriteLine(minimumcoins(arr, N));
}
}
// This code is contributed by AnkThon
Javascript
输出
2
时间复杂度: O(N)
辅助空间: O(1)