Stone Game VI

medium dp greedy sorting game theory

Problem

Alice and Bob take turns picking stones (Alice first). Stone i is worth aliceValues[i] to Alice and bobValues[i] to Bob. Each plays optimally to maximize their own total. Return 1 if Alice wins, -1 if Bob wins, 0 if a tie.

InputaliceValues = [1,3], bobValues = [2,1]
Output1
Sort stones by alice[i] + bob[i] descending. Alice takes the odd positions of that order, Bob the even ones.

def stone_game_vi(aliceValues, bobValues):
    n = len(aliceValues)
    order = sorted(range(n), key=lambda i: -(aliceValues[i] + bobValues[i]))
    a, b = 0, 0
    for turn, i in enumerate(order):
        if turn % 2 == 0:
            a += aliceValues[i]
        else:
            b += bobValues[i]
    return (a > b) - (a < b)
function stoneGameVI(aliceValues, bobValues) {
  const n = aliceValues.length;
  const order = [...Array(n).keys()];
  order.sort((x, y) => (aliceValues[y] + bobValues[y]) - (aliceValues[x] + bobValues[x]));
  let a = 0, b = 0;
  order.forEach((i, turn) => {
    if (turn % 2 === 0) a += aliceValues[i];
    else b += bobValues[i];
  });
  return a > b ? 1 : a < b ? -1 : 0;
}
class Solution {
    public int stoneGameVI(int[] aliceValues, int[] bobValues) {
        int n = aliceValues.length;
        Integer[] order = new Integer[n];
        for (int i = 0; i < n; i++) order[i] = i;
        Arrays.sort(order, (x, y) ->
            (aliceValues[y] + bobValues[y]) - (aliceValues[x] + bobValues[x]));
        long a = 0, b = 0;
        for (int turn = 0; turn < n; turn++) {
            if (turn % 2 == 0) a += aliceValues[order[turn]];
            else b += bobValues[order[turn]];
        }
        return Long.compare(a, b);
    }
}
int stoneGameVI(vector<int>& aliceValues, vector<int>& bobValues) {
    int n = aliceValues.size();
    vector<int> order(n);
    iota(order.begin(), order.end(), 0);
    sort(order.begin(), order.end(), [&](int x, int y) {
        return aliceValues[x] + bobValues[x] > aliceValues[y] + bobValues[y];
    });
    long long a = 0, b = 0;
    for (int turn = 0; turn < n; turn++) {
        if (turn % 2 == 0) a += aliceValues[order[turn]];
        else b += bobValues[order[turn]];
    }
    return (a > b) - (a < b);
}
Time: O(n log n) Space: O(n)