Can I Win in C++


Suppose in a game called "100 games," two players take turns adding, to a running total, any integer from 1 through 10. The player who first causes the running total to reach or exceed 100, he/she wins. So what if we change the game so that players cannot re-use integers?

For example, if two players take turns drawing from a common pool of numbers of 1..15 without replacement until they reach a total >= 100.

So suppose given an integer maxChoosableInteger and another integer desired total, determine if the first player to move can force a win, assuming both players play optimally.

We can always assume that maxChoosableInteger will not be larger than the value of 20 and the desired total will not be larger than 300. So if the input is maxChooseableInteger = 20, and the desired total is 11, then the result will be false. No matter the first player chooses, the first player will lose.

To solve this, we will follow these steps −

  • Create an array called dp of size 2^21

  • Define a method solve(), this will take n, s, and mask.

  • if s <= 0, then return false

  • if dp[mask] is not -1, then return dp[mask]

  • set ret := false

  • for I in range 1 to n

    • if (shifting mask I bits to the right) is odd, then

      • ret := ret OR (inverse of solve(n, s – i, mask XOR 2^i))

  • dp[mask] := ret

  • return ret

  • From the main method, do the following

  • if desiredTotal <= 0, then return true

  • for I in range 0 to 2^21

    • dp[i] := -1

  • if desiredTotal > (sum of first n numbers), then return false

  • return solve(n, desiredTotal, 0)

Example (C++)

Let us see the following implementation to get a better understanding −

 Live Demo

#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
   int dp[1 << 21];
   bool solve(int n, int s, int mask){
      if(s <= 0) return false;
      if(dp[mask] != -1) return dp[mask];
      bool ret = false;
      for(int i = 1; i <= n; i++){
         if(!((mask >> i) & 1)){
            ret |= (!solve(n, s - i, (mask ^ (1 << i))));
         }
      }
      return dp[mask] = ret;
   }
   bool canIWin(int n, int desiredTotal) {
      if(desiredTotal <= 0) return true;
      for(int i = 0; i < (1 << 21); i++)dp[i] = -1;
      if(desiredTotal > (n * (n + 1)/ 2))return false;
      return solve(n, desiredTotal, 0);
   }
};
main() {
Solution ob;
cout << (ob.canIWin(10,11));
}

Input

10
11

Output

0

Updated on: 29-Apr-2020

169 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements