给定大小为N的二进制数组arr []和两个播放器A和B。任务是通过根据给定的约束选择玩家的得分来最小化玩家A的得分:
- 每个玩家可以依次从数组中删除一个或两个连续的数字,并按从左到右的顺序删除元素。
- 从玩家A开始,玩家将有交替的回合。
- 最初,罚分是0 ,并且增加了数字,而玩家A则将其删除。
例子:
Input: arr[] = {1, 1, 1, 1, 0, 0, 1}
Output: 2
Explanation: Elements can be removed as follows:
Turn 1: Player A remove the element at index 0. Therefore, penalty is 0 + 1 = 1.
Turn 2: Player B remove the elements at indices 1 and 2. Still, penalty is 1.
Turn 3: Player A remove the element at index 3. Therefore, penalty is 1 + 1 = 2.
Turn 4: Player B remove the element at index 4. Still, penalty is 2.
Turn 5: Player A remove the element at index 5. Still, penalty is 2 + 0 = 2.
Turn 6: Player B remove the element at index 6. Still, penalty is 2.
Hence, the minimum score for player A = 2.
Input: arr[] = {1, 0, 1, 1, 0, 1, 1, 1}
Output: 2
Explanation: Elements can be removed as follows:
Turn 1: Player A remove the element at indices 0 and 1. Therefore, penalty is 0 + 1 + 0 = 1.
Turn 2: Player B remove the elements at indices 2 and 3. Still, penalty is 1.
Turn 3: Player A remove the element at index 4. Therefore, penalty is 1 + 0 = 1.
Turn 4: Player B remove the elements at indices 5 and 6. Still, penalty is 1.
Turn 5: Player A remove the element at index 7. Therefore, penalty is 2 + 1 = 2.
Hence, the minimum score for player A = 2.
天真的方法:最简单的方法是尝试所有可能的组合以从给定数组中删除元素。每次都有两个可能的选项,即可以删除一个或两个连续的元素。在从1到N – 1的每个位置上,有2个选择。因此,可以进行2 N种可能的组合。可以找到每种组合的罚款,并在其中列出最低罚款。
时间复杂度: O(2 N )
辅助空间: O(1)
高效方法:为了优化上述方法,其思想是使用动态编程。可以使用以下dp转换来解决,其中dp [i] [0]存储从i到N – 1的最小惩罚。如果玩家A开始从索引i中进行选择。类似地,可以为玩家B定义dp [i] [1] 。
On player A’s turn:
dp[i][0] = min(dp(i+1, 1)+arr[i], dp(i+2, 1)+arr[i+1]+arr[i+2])
where,
i denotes the current position.
1 denotes that it is B’s turn on next state.
On player B’s turn:
dp[i][1] = min(dp(i+1, 0), dp(i+2, 0))
where,
i denotes the current position.
0 denotes that it is A’s turn on next state.
请按照以下步骤解决问题:
- 可以使用带记忆的递归。对于基本条件,请检查当前位置是否超过或变为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)