给定的阵列ARR []的大小N,表示指定到N石头,两个玩家,PLAYER1和Player2值,起到交替匝的游戏。在每一回合中,玩家可以从第一批剩余的石头中取出1、2或3颗石头,并将所有移除的石头的总和添加到玩家的分数中。考虑到两个玩家都玩得最好,任务是打印游戏的赢家。如果双方以相同的分数结束游戏,则打印“Tie” 。
例子:
Input: arr[] = {1, 2, 3, 7}
Output: Player2
Explanation: Player1 will always lose in an optimal scenario.
Input: arr[] = {1, 2, 3, -9}
Output: Player1
Explanation: Player1 must choose all the three piles at the first move to win and leave Player2 with negative score.
If Player1 chooses only one stone his score will be 1 and the next move Player2 score becomes 5.
The next move Player1 will take the stone with value = -9 and lose.
If Player1 chooses two piles his score will be 3 and the next move Player2 score becomes 3.
The next move Player1 will take the stone with value = -9 and also lose.
朴素的方法:简单的方法是选择可以最大化石头价值总和的石头数量。当两个玩家都以最佳方式玩并且玩家 1 开始游戏时,玩家 1 选择 1 或 2 或 3 颗棋子,并将剩余的棋子传递给下一个玩家。因此,必须从 Player1 的分数中减去 Player2 的分数。这个想法是使用递归来解决问题。令 Player1 的最大分数为res ,这是递归调用后得到的。
- 如果结果res > 0 ,则 Player1 获胜
- 如果结果为res < 0 ,则 Player2 获胜
- 如果结果为res == 0 ,则为平局。
递归树看起来像这样,其中一些子问题重复多次。
请按照以下步骤解决问题:
- 声明一个递归函数,比如maxScore(i) ,如果游戏从索引i开始,则计算Player1的最大分数
- 如果i ≥ n的值,则返回0 。
- 初始化一个变量,比如score为 INT_MIN,用来存储 Player1 的最大分数
- 挑选 1 块石头: score = max(score, arr[i] – maxScore(i + 1))
- 挑选 2 个石头,即(i + 1 < N) : score = max(score, arr[i] + arr[i + 1] – maxScore(i + 2))
- 选择 3 个石头,即(i + 2 < N) : score = max(score, arr[i] + arr[i + 1] + arr[i + 2] – maxScore(i + 3))
- 返回score的值。
- 将maxScore(0)的值存储在变量res 中。
- 如果解析度> 0的值,则打印“PLAYER1”,如果RES <0,打印“Player2”,否则输出“平局”。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the maximum score of Player1
int maximumStonesUtil(int* arr, int n, int i)
{
// Base Case
if (i >= n)
return 0;
// Variable to store maximum score
int ans = INT_MIN;
// Pick one stone
ans = max(ans,
arr[i] - maximumStonesUtil(arr, n, i + 1));
// Pick 2 stones
if (i + 1 < n)
ans = max(ans,
arr[i] + arr[i + 1]
- maximumStonesUtil(arr, n, i + 2));
// Pick 3 stones
if (i + 2 < n)
ans = max(ans,
arr[i] + arr[i + 1] + arr[i + 2]
- maximumStonesUtil(arr, n, i + 3));
// Return the score of the player
return ans;
}
// Function to find the winner of the game
string maximumStones(int* arr, int n)
{
// Store the result
int res = maximumStonesUtil(arr, n, 0);
// Player 1 wins
if (res > 0)
return "Player1";
// PLayer 2 wins
else if (res < 0)
return "Player2";
// Tie
else
return "Tie";
}
// Driver Code
int main()
{
// Given Input
int arr[] = { 1, 2, 3, 7 };
int n = sizeof(arr) / sizeof(arr[0]);
// Function Call
cout << maximumStones(arr, n);
return 0;
}
Java
// Java program for the above approach
class GFG{
// Function to find the maximum score of Player1
static int maximumStonesUtil(int[] arr, int n,
int i)
{
// Base Case
if (i >= n)
return 0;
// Variable to store maximum score
int ans = Integer.MIN_VALUE;
// Pick one stone
ans = Math.max(ans, arr[i] - maximumStonesUtil(
arr, n, i + 1));
// Pick 2 stones
if (i + 1 < n)
ans = Math.max(ans, arr[i] + arr[i + 1] -
maximumStonesUtil(arr, n, i + 2));
// Pick 3 stones
if (i + 2 < n)
ans = Math.max(
ans,
arr[i] + arr[i + 1] + arr[i + 2]
- maximumStonesUtil(arr, n, i + 3));
// Return the score of the player
return ans;
}
// Function to find the winner of the game
static String maximumStones(int[] arr, int n)
{
// Store the result
int res = maximumStonesUtil(arr, n, 0);
// Player 1 wins
if (res > 0)
return "Player1";
// PLayer 2 wins
else if (res < 0)
return "Player2";
// Tie
else
return "Tie";
}
// Driver code
public static void main(String[] args)
{
int arr[] = { 1, 2, 3, 7 };
int n = arr.length;
// Function Call
System.out.println(maximumStones(arr, n));
}
}
// This code is contributed by abhinavjain194
Python3
# Python3 program for the above approach
import sys
# Function to find the maximum score of Player1
def maximumStonesUtil(arr, n, i):
# Base Case
if (i >= n):
return 0
# Variable to store maximum score
ans = -sys.maxsize-1;
# Pick one stone
ans = max(
ans, arr[i] - maximumStonesUtil(
arr, n, i + 1))
# Pick 2 stones
if (i + 1 < n):
ans = max(
ans, arr[i] + arr[i + 1]- maximumStonesUtil(
arr, n, i + 2))
# Pick 3 stones
if (i + 2 < n):
ans = max(
ans, arr[i] + arr[i + 1] + arr[i + 2]-
maximumStonesUtil(arr, n, i + 3));
# Return the score of the player
return ans
# Function to find the winner of the game
def maximumStones(arr, n):
# Store the result
res = maximumStonesUtil(arr, n, 0)
# Player 1 wins
if (res > 0):
return "Player1"
# PLayer 2 wins
elif(res < 0):
return "Player2"
# Tie
else:
return "Tie"
# Driver Code
if __name__ == '__main__':
# Given Input
arr = [ 1, 2, 3, 7 ]
n = len(arr)
# Function Call
print(maximumStones(arr, n))
# This code is contributed by SURENDRA_GANGWAR
C#
// C# program for the above approach
using System;
class GFG
{
// Function to find the maximum score of Player1
static int maximumStonesUtil(int[] arr, int n,
int i)
{
// Base Case
if (i >= n)
return 0;
// Variable to store maximum score
int ans = Int32.MinValue;
// Pick one stone
ans = Math.Max(ans, arr[i] - maximumStonesUtil(
arr, n, i + 1));
// Pick 2 stones
if (i + 1 < n)
ans = Math.Max(ans, arr[i] + arr[i + 1] -
maximumStonesUtil(arr, n, i + 2));
// Pick 3 stones
if (i + 2 < n)
ans = Math.Max(
ans,
arr[i] + arr[i + 1] + arr[i + 2]
- maximumStonesUtil(arr, n, i + 3));
// Return the score of the player
return ans;
}
// Function to find the winner of the game
static String maximumStones(int[] arr, int n)
{
// Store the result
int res = maximumStonesUtil(arr, n, 0);
// Player 1 wins
if (res > 0)
return "Player1";
// PLayer 2 wins
else if (res < 0)
return "Player2";
// Tie
else
return "Tie";
}
// Driver Code
public static void Main()
{
int[] arr = { 1, 2, 3, 7 };
int n = arr.Length;
// Function Call
Console.WriteLine(maximumStones(arr, n));
}
}
// This code is contributed by code_hunt.
Javascript
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the maximum score of Player 1
int maximumStonesUtil(int* arr, int n, int i,
vector& dp)
{
// Base Case
if (i >= n)
return 0;
int& ans = dp[i];
// If the result is already computed, then
// return the result
if (ans != -1)
return ans;
// Variable to store maximum score
ans = INT_MIN;
// Pick one stone
ans = max(
ans, arr[i] - maximumStonesUtil(arr, n, i + 1, dp));
// Pick 2 stones
if (i + 1 < n)
ans = max(ans, arr[i] + arr[i + 1]
- maximumStonesUtil(arr, n,
i + 2, dp));
// Pick 3 stones
if (i + 2 < n)
ans = max(ans, arr[i] + arr[i + 1] + arr[i + 2]
- maximumStonesUtil(arr, n,
i + 3, dp));
// Return the score of the player
return ans;
}
// Function to find the winner of the game
string maximumStones(int* arr, int n)
{
// Create a 1D table, dp of size N
vector dp(n, -1);
// Store the result
int res = maximumStonesUtil(arr, n, 0, dp);
// Player 1 wins
if (res > 0)
return "Player1";
// PLayer 2 wins
else if (res < 0)
return "Player2";
// Tie
else
return "Tie";
}
// Driver Code
int main()
{
// Given Input
int arr[] = { 1, 2, 3, 7 };
int n = sizeof(arr) / sizeof(arr[0]);
// Function Call
cout << maximumStones(arr, n);
return 0;
}
Player2
时间复杂度: O(3 N )
辅助空间: O(N)
高效的方法:为了优化上述方法,思想是使用动态规划。给定的问题具有最优子结构属性和重叠子问题。通过创建一个大小为N 的dp的一维表来使用记忆化来存储递归调用的结果。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the maximum score of Player 1
int maximumStonesUtil(int* arr, int n, int i,
vector& dp)
{
// Base Case
if (i >= n)
return 0;
int& ans = dp[i];
// If the result is already computed, then
// return the result
if (ans != -1)
return ans;
// Variable to store maximum score
ans = INT_MIN;
// Pick one stone
ans = max(
ans, arr[i] - maximumStonesUtil(arr, n, i + 1, dp));
// Pick 2 stones
if (i + 1 < n)
ans = max(ans, arr[i] + arr[i + 1]
- maximumStonesUtil(arr, n,
i + 2, dp));
// Pick 3 stones
if (i + 2 < n)
ans = max(ans, arr[i] + arr[i + 1] + arr[i + 2]
- maximumStonesUtil(arr, n,
i + 3, dp));
// Return the score of the player
return ans;
}
// Function to find the winner of the game
string maximumStones(int* arr, int n)
{
// Create a 1D table, dp of size N
vector dp(n, -1);
// Store the result
int res = maximumStonesUtil(arr, n, 0, dp);
// Player 1 wins
if (res > 0)
return "Player1";
// PLayer 2 wins
else if (res < 0)
return "Player2";
// Tie
else
return "Tie";
}
// Driver Code
int main()
{
// Given Input
int arr[] = { 1, 2, 3, 7 };
int n = sizeof(arr) / sizeof(arr[0]);
// Function Call
cout << maximumStones(arr, n);
return 0;
}
Player2
时间复杂度: O(N)
辅助空间: O(N)