美文网首页
Coins in a line III

Coins in a line III

作者: Star_C | 来源:发表于2018-04-06 23:13 被阅读0次

Question

from lintcode
There are n coins in a line. Two players take turns to take a coin from one of the two ends of the line until there are no more coins left. The player with the larger amount of money wins.

Could you please decide the first player will win or lose?

Example
Given array A = [3,2,2], return true.

Given array A = [1,2,4], return true.

Given array A = [1,20,4], return false.

Idea

We want to know if the first player can win, i.e. if he can win in the case where

  • he tries to get the maximum amount as he can
  • the second player tries to minimize his income as possible

/**
 *  maxTotal[left][right] means the maximum amount that the first player
 *  can have.
 *
 *  see calculate() for the dynamic programming function
 */
public class Solution {
    /**
     * @param values: an array of integers
     * @return: a boolean which equals to true if the first player will win
     */
    public boolean firstWillWin(int[] values) {

        if (values.length == 0) return false;

        int n = values.length;
        int[][] maxTotal = new int[n][n];
        boolean[][] calculated =new boolean[n][n];

        int sum = 0;
        for(int now : values)
            sum += now;

        return sum < 2* calculate(0,values.length - 1, maxTotal, calculated, values);
    }

    int calculate(int left, int right, int [][]maxTotal, boolean [][]calculated, int []values) {

        if(calculated[left][right])
            return maxTotal[left][right];

        calculated[left][right] = true;

        if (left == right) {
            maxTotal[left][right] = values[left];
        } else if(left + 1 == right) {
            maxTotal[left][right] = Math.max(values[left], values[right]);
        } else {

            int  firstPlayerPickLeft = values[left] +
                    // why Math.min? cuz it's opponent's turn, whose goal is to make the first player lose
                    Math.min(
                        // opponent picks left element of the remained list
                        calculate(left + 2, right, maxTotal, calculated, values),
                        // opponent picks right element of the remained list
                        calculate(left + 1, right - 1, maxTotal, calculated, values)
                    );

            int  firstPlayerPickRight = values[right] +
                    // why Math.min? cuz it's opponent's turn, whose goal is to make the first player lose
                    Math.min(
                            // opponent picks left element of the remained list
                            calculate(left, right - 2, maxTotal, calculated, values),
                            // opponent picks right element of the remained list
                            calculate(left + 1, right - 1, maxTotal, calculated, values)
                    );

            maxTotal[left][right] = Math.max(firstPlayerPickLeft, firstPlayerPickRight);
        }

        return maxTotal[left][right];
    }
}

相关文章

网友评论

      本文标题:Coins in a line III

      本文链接:https://www.haomeiwen.com/subject/rkkehftx.html