排成一条线的纸牌博弈问题

链接
给定一个整型数组arr,代表数值不同的纸牌排成一条线,玩家A和玩家B依次拿走每张纸牌,规定玩家A先拿,玩家B后拿,但是每个玩家每次只能拿走最左和最右的纸牌,玩家A和玩家B绝顶聪明。请返回最后的获胜者的分数。

import java.util.Scanner;

public class Main {

    private static int first(int[] arr, int L, int R) {
        if (L == R) {
            return 0;
        }
        return Math.max(arr[L] + second(arr, L + 1, R), arr[R] + second(arr, L, R - 1));
    }

    private static int second(int[] arr, int L, int R) {
        if (L == R) {
            return 0;
        }
        return Math.min(first(arr, L + 1, R), first(arr, L, R - 1));
    }

    private static int solve(int[] arr) {
        int n = arr.length;
        int[][] first = new int[n][n];
        int[][] second = new int[n][n];
        for (int i = 0; i < n; ++i) {
            first[i][i] = arr[i];
        }

        for (int L = n - 2; L >= 0; --L) {
            for (int R = L + 1; R < n; ++R) {
                first[L][R] = Math.max(arr[L] + second[L + 1][R], arr[R] + second[L][R - 1]);
                second[L][R] = Math.min(first[L + 1][R], first[L][R - 1]);
            }
        }

        return Math.max(first[0][n - 1], second[0][n - 1]);
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            int n = in.nextInt();
            int[] arr = new int[n];
            for (int i = 0; i < n; ++i) {
                arr[i] = in.nextInt();
            }
            System.out.println(solve(arr));
        }
    }
}
上一篇:Codeforces Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2)


下一篇:倒数第几个(本质上是将倒数 转化成(两个点之间)具体的距离)