Stone Game in C++


Suppose we have two players Alex and Lee they play a game with piles of stones. There are an even number of piles that are arranged in a row, and each pile has some number of stones piles[i]. The objective of the game is to end with the most stones. When the total number of stones is odd, there are no ties. Alex and Lee take turns, with Alex starting first. In each turn, a player takes the entire pile of stones from either the beginning or the end of the row. This will be continued until there are no more piles left, at which point the person with the most stones wins. Assume that Alex and Lee play optimally, check whether Alex wins the game or not. So if the input is like [5,3,4,5], then the result will be true, as Alex has started first, he can only take the first 5 or the last 5. Now if he takes the first 5, so that the row becomes [3, 4, 5]. If Lee takes 3, after that, then the board is [4, 5], and Alex takes 5 to win with 10 points. When Lee takes the last 5, then the board is [3, 4], and Alex takes 4 to win with 9 points. So this indicates that taking the first 5 was a winning move for Alex, answer is true.

To solve this, we will follow these steps −

  • n := size of piles array

  • create a matrix dp of size n x n, create another array called pre of size n + 1

  • for i in range 0 to n – 1

    • pre[i + 1] := pre[i] + piles[i]

  • for l in range 2 to n −

    • for i := 0, j := l – 1, j < n, increase i and j by 1

      • dp[i, j] := max of piles[j] + pre[j] – pre[i] – dp[i, j – 1] and piles[i] + pre[i + 2] – pre[j] + dp[i + 1, j]

  • return true when dp[0, n – 1] > dp[0, n – 1] – pre[n]

Let us see the following implementation to get better understanding −

Example

 Live Demo

#include <bits/stdc++.h>
using namespace std;
class Solution {
   public:
   bool stoneGame(vector<int>& piles) {
      int n = piles.size();
      vector < vector <int> > dp(n,vector <int>(n));
      vector <int> pre(n + 1);
      for(int i = 0; i < n; i++){
         pre[i + 1] = pre[i] + piles[i];
      }
      for(int l = 2; l <= n; l++){
         for(int i = 0, j = l - 1; j < n; i++, j++){
            dp[i][j] = max(piles[j] + pre[j] - pre[i] - dp[i][j - 1], piles[i] + pre[i + 2] - pre[j] +             dp[i       + 1][j]);
         }
      }
      return dp[0][n - 1] > dp[0][n - 1] - pre[n];
   }
};
main(){
   vector<int> v = {5,3,4,5};
   Solution ob;
   cout << (ob.stoneGame(v));
}

Input

[5,3,4,5]

Output

1

Updated on: 30-Apr-2020

352 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements