Coins in a Line III

There are n coins in a line. Two players take turns to take a coin from one of the 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?

Have you met this question in a real interview? Yes
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.

Challenge

Follow Up Question:

If n is even. Is there any hacky algorithm that can decide whether first player will win or lose in O(1) memory and O(n) time?

Tags Expand

Dynamic Programming Array Game Theory

思路

  • 画图找规律
  • 再通过简单的case代入,去寻找初始化
  • 通过初始化写循环条件
  • dp[i][j] 此时,先手的人从剩下的硬币 values[i] 到values[j]中,所能获得的最大价值
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) {
        // write your code here
        if (values == null || values.length == 0) {
            return false;
        }
        if (values.length == 1) {
            return true;
        }

        int n = values.length;
        int sum = 0;

        for (int i = 0; i < n; i++) {
            sum += values[i];
        }

        int[][] dp = new int[n][n];

        for (int i = 0; i < n; i++) {
            dp[i][i] = values[i];
        }
        for (int i = 0; i < n - 1; i++) {
            dp[i][i + 1] = Math.max(values[i], values[i + 1]);
        }

        for (int dis = 2; dis < n; dis++ ) {
            for (int i = 0, j = i + dis; i < n - 2 && j < n; i++, j++) {
                int min1 = Math.min(dp[i + 2][j], dp[i + 1][j - 1]) + values[i];
                int min2 = Math.min(dp[i + 1][j - 1], dp[i][j - 2]) + values[j];
                dp[i][j] = Math.max(min1, min2);
            }
        }

        return dp[0][n - 1] > sum / 2 ? true : false;
    }
}

results matching ""

    No results matching ""