📌  相关文章
📜  通过从给定的二进制数组中选择一个或两个连续的数组元素,玩家可能获得的最低分数

📅  最后修改于: 2021-09-24 03:18:54             🧑  作者: Mango

给定一个大小为N的二进制数组arr[]和两个玩家AB 。任务是通过根据给定的约束选择玩家的分数来最小化玩家A的分数:

  • 每个玩家可以轮流从数组中删除一个或两个连续的数字,并按照从左到右的顺序删除元素。
  • 玩家将有交替的回合,从玩家A开始。
  • 最初,惩罚为0并按数字增加,玩家A将其移除。

例子:

朴素的方法:最简单的方法是尝试所有可能的组合以从给定数组中删除元素。每次都有两种可能的选择,即可以删除一个或两个连续的元素。在每个位置,从1N – 1 ,有2 个选择。因此,可以进行2 N 种可能的组合。可以找到每个组合的惩罚,并在其中打印最小惩罚。

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

高效的方法:为了优化上述方法,思想是使用动态规划。它可以使用以下dp转换来解决,其中dp[i][0]存储从iN – 1的最小惩罚。如果玩家A从索引i开始选择。类似地,可以为玩家B定义dp[i][1]

请按照以下步骤解决问题:

  • 可以使用带记忆的递归。对于基本条件,检查当前位置是否超过或变为N ,返回0
  • 根据玩家的回合应用上面定义的转换并返回最小答案。
  • 初始化递归函数,玩家 A 的回合和惩罚为0
  • 对于每个递归调用,将计算的最小惩罚存储在映射M 中,以避免为重叠子问题计算。
  • 上述递归调用结束后,打印玩家A最低分数

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Stores the minimum score for each
// states as map, ans>
map, int> m;
 
// Function to find the minimum score
// after choosing element from array
int findMinimum(int a[], int n, int pos,
                int myturn)
{
    // Return the stored state
    if (m.find({ pos, myturn }) != m.end()) {
        return m[{ pos, myturn }];
    }
 
    // Base Case
    if (pos >= n) {
        return 0;
    }
 
    // Player A's turn
    if (!myturn) {
 
        // Find the minimum score
        int ans = min(
            findMinimum(a, n, pos + 1, !myturn)
                + a[pos],
            findMinimum(a, n, pos + 2, !myturn)
                + a[pos] + a[pos + 1]);
 
        // Store the current state
        m[{ pos, myturn }] = ans;
 
        // Return the result
        return ans;
    }
 
    // Player B's turn
    if (myturn) {
 
        // Find minimum score
        int ans = min(
            findMinimum(a, n, pos + 1, !myturn),
            findMinimum(a, n, pos + 2, !myturn));
 
        // Store the current state
        m[{ pos, myturn }] = ans;
 
        // Return the result
        return ans;
    }
    return 0;
}
 
// Function that finds the minimum
// penality after choosing element
// from the given binary array
int countPenality(int arr[], int N)
{
    // Starting position of choosing
    // element from array
    int pos = 0;
 
    // 0 denotes player A turn
    // 1 denotes player B turn
    int turn = 0;
 
    // Function Call
    return findMinimum(arr, N, pos, turn);
}
 
// Print the answer for player A and B
void printAnswer(int* arr, int N)
{
 
    // Minimum penalty
    int a = countPenality(arr, N);
 
    // Calculate sum of all arr elements
    int sum = 0;
    for (int i = 0; i < N; i++) {
        sum += arr[i];
    }
 
    // Print the minimum score
    cout << a;
}
// Driver Code
int main()
{
    // Given array arr[]
    int arr[] = { 1, 0, 1, 1, 0, 1, 1, 1 };
 
    int N = sizeof(arr) / sizeof(arr[0]);
 
    // Function Call
    printAnswer(arr, N);
 
    return 0;
}


Java
// Java program for the above approach
import java.io.*;
import java.util.*;
 
class GFG{
     
static class R
{
    int x, y;
     
    public R(int x, int y)
    {
        this.x = x;
        this.y = y;
    }
}
 
// Stores the minimum score for each
// states as map, ans>
static HashMap m = new HashMap<>();
 
// Function to find the minimum score
// after choosing element from array
public static int findMinimum(int[] arr, int N,
                              int pos, int turn)
{
     
    // Return the stored state
    R x = new R(pos, turn);
     
    if (m.containsKey(x))
    {
        return m.get(x);
    }
 
    // Base Case
    if (pos >= N - 1)
    {
        return 0;
    }
 
    // Player A's turn
    if (turn == 0)
    {
         
        // Find the minimum score
        int ans = Math.min(
            findMinimum(arr, N, pos + 1, 1) + arr[pos],
            findMinimum(arr, N, pos + 2, 1) + arr[pos] +
                            arr[pos + 1]);
 
        // Store the current state
        R v = new R(pos, turn);
        m.put(v, ans);
 
        // Return the result
        return ans;
    }
 
    // Player B's turn
    if (turn != 0)
    {
         
        // Find minimum score
        int ans = Math.min(
            findMinimum(arr, N, pos + 1, 0),
            findMinimum(arr, N, pos + 2, 0));
 
        // Store the current state
        R v = new R(pos, turn);
        m.put(v, ans);
 
        // Return the result
        return ans;
    }
    return 0;
}
 
// Function that finds the minimum
// penality after choosing element
// from the given binary array
public static int countPenality(int[] arr, int N)
{
     
    // Starting position of choosing
    // element from array
    int pos = 0;
 
    // 0 denotes player A turn
    // 1 denotes player B turn
    int turn = 0;
 
    // Function Call
    return findMinimum(arr, N, pos, turn) + 1;
}
 
// Function to print the answer
public static void printAnswer(int[] arr, int N)
{
     
    // Minimum penalty
    int a = countPenality(arr, N);
     
    // Calculate sum of all arr elements
    int sum = 0;
    for(int i = 0; i < N; i++)
    {
        sum += arr[i];
    }
     
    // Print the minimum score
    System.out.println(a);
}
 
// Driver code
public static void main(String[] args)
{
    int arr[] = { 1, 0, 1, 1, 0, 1, 1, 1 };
    int N = 8;
 
    // Function Call
    printAnswer(arr, N);
}
}
 
// This code is contributed by RohitOberoi


Python3
# Python3 program for the above approach
  
# Stores the minimum score for each
# states as map, ans>
m = dict()
  
# Function to find the minimum score
# after choosing element from array
def findMinimum(a, n, pos, myturn):
 
    # Return the stored state
    if (pos, myturn) in m:
        return m[( pos, myturn )];
     
    # Base Case
    if (pos >= n - 1):
        return 0;
      
    # Player A's turn
    if (not myturn):
  
        # Find the minimum score
        ans = min( findMinimum(a, n, pos + 1, not myturn) + a[pos],
                     findMinimum(a, n, pos + 2, not myturn) + a[pos] + a[pos + 1]);
  
        # Store the current state
        m[( pos, myturn )] = ans;
  
        # Return the result
        return ans;
  
    # Player B's turn
    if (myturn):
  
        # Find minimum score
        ans = min( findMinimum(a, n, pos + 1, not myturn),
                    findMinimum(a, n, pos + 2, not myturn));
  
        # Store the current state
        m[( pos, myturn )] = ans;
  
        # Return the result
        return ans;
     
    return 0;
   
# Function that finds the minimum
# penality after choosing element
# from the given binary array
def countPenality(arr, N):
 
    # Starting position of choosing
    # element from array
    pos = 0;
  
    # 0 denotes player A turn
    # 1 denotes player B turn
    turn = False;
  
    # Function Call
    return findMinimum(arr, N, pos, turn) + 1;
 
# Print the answer for player A and B
def printAnswer(arr, N):
  
    # Minimum penalty
    a = countPenality(arr, N);
  
    # Calculate sum of all arr elements
    sum = 0;
     
    for i in range(N):
     
        sum += arr[i];
      
    # Print the minimum score
    print(a)
     
# Driver Code
if __name__=='__main__':
 
    # Given array arr[]
    arr = [ 1, 0, 1, 1, 0, 1, 1, 1 ]
  
    N = len(arr)
  
    # Function Call
    printAnswer(arr, N);
 
# This code is contributed by rutvik_56


输出:
2

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

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程