问题描述
给定一个整型数组arr,代表数组不同的纸牌,
玩家A和B依次拿走一张纸牌,
规定玩家A先拿,玩家B后拿,
但每次玩家只能拿走最左边或者最右边的纸牌,
玩家A和B都会根据最优方案拿牌,
返回最后获胜者的分数。
三种解决方法
public class 拿纸牌 {
public static int way1(int[] arr) {
int res = 0;
res = Math.max(first1(0, arr.length - 1, arr), second1(0, arr.length - 1, arr));
return res;
}
public static int first1(int l, int r, int[] arr) {
if (l == r) {
return arr[l];
}
return Math.max(arr[l] + second1(l+1, r, arr), arr[r] + second1(l, r-1, arr));
}
public static int second1(int l, int r, int[] arr) {
if (l == r) {
return 0;
}
return Math.min(first1(l+1, r, arr), first1(l, r-1, arr));
}
public static int way2(int[] arr) {
int res = 0;
int n = arr.length;
int[][] f = new int[n][n];
int[][] g = new int[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
f[i][j] = -1;
g[i][j] = -1;
}
}
res = Math.max(first2(0, arr.length - 1, arr, f, g), second2(0, arr.length - 1, arr, f, g));
return res;
}
public static int first2(int l, int r, int[] arr, int[][] f, int[][] g) {
if (f[l][r] != -1) {
return f[l][r];
}
if (l == r) {
return arr[l];
}
int ans = Math.max(arr[l] + second2(l+1, r, arr, f, g), arr[r] + second2(l, r-1, arr, f, g));
f[l][r] = ans;
return ans;
}
public static int second2(int l, int r, int[] arr, int[][] f, int[][] g) {
if (g[l][r] != -1) {
return g[l][r];
}
if (l == r) {
return 0;
}
int ans = Math.min(first2(l+1, r, arr, f, g), first2(l, r-1, arr, f, g));
g[l][r] = ans;
return ans;
}
public static int way3(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 i = 1; i < n; i++) {
int col = i;
int row = 0;
while (col < n && row < n) {
first[row][col] = Math.max(arr[row] + second[row+1][col],
arr[col] + second[row][col-1]);
second[row][col] = Math.min(first[row+1][col],
first[row][col-1]);
col ++;
row ++;
}
}
return Math.max(first[0][n-1], second[0][n-1]);
}
public static void main(String[] args) {
int[] arr = {3, 7, 2, 1};
int[] arr2 = {7, 4, 16, 15, 1};
System.out.println(way1(arr2));
System.out.println(way2(arr2));
System.out.println(way3(arr2));
}
}
动态规划法详解
