题目描述
给定一个整型数组arr,代表数值不同的纸牌排成一条线,玩家A和玩家B依次拿走每张纸牌,规定玩家A先拿,玩家B后拿,但是每个玩家每次只能拿走最左和最右的纸牌,玩家A和玩家B绝顶聪明。请返回最后的获胜者的分数。
输入描述:
输出包括两行,第一行一个整数n(1≤n≤5000)(1 \leq n \leq 5000 )(1≤n≤5000),代表数组arr长度,第二行包含n个整数,第i个代表arri( 1 \leq arr[i] \leq 10^5 )(1≤arr[i]≤105)。
输出描述:
输出一个整数,代表最后获胜者的分数。
示例1
输入
4
1 2 100 4
输出
101
解法一:递归
import java.io.*;
import java.util.*;
public class Main{
public static void main(String[] args)throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int len = Integer.parseInt(br.readLine());
String[] ss = br.readLine().trim().split(" ");
int[] arr = new int[len];
for(int i=0;i<len;i++){
arr[i] = Integer.parseInt(ss[i]);
}
int res = getRes(arr);
System.out.println(res);
}
public static int getRes(int[] arr){
if(arr==null||arr.length==0) return 0;
return Math.max(f(arr,0,arr.length-1),s(arr,0,arr.length-1));
}
public static int f(int[] arr,int l,int r){
if(l==r) return arr[l];
return Math.max(arr[l]+s(arr,l+1,r),arr[r]+s(arr,l,r-1));
}
public static int s(int[] arr,int l,int r){
if(l==r) return 0;
return Math.min(f(arr,l+1,r),f(arr,l,r-1));
}
}
解法二:动态规划
可以继续空间压缩
import java.io.*;
import java.util.*;
public class Main{
public static void main(String[] args)throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int len = Integer.parseInt(br.readLine());
String[] ss = br.readLine().trim().split(" ");
int[] arr = new int[len];
for(int i=0;i<len;i++){
arr[i] = Integer.parseInt(ss[i]);
}
int res = getRes(arr);
System.out.println(res);
}
public static int getRes(int[] arr){
if(arr==null||arr.length==0) return 0;
int[][] f = new int[arr.length][arr.length];
int[][] s = new int[arr.length][arr.length];
for(int i=0;i<arr.length;i++){
f[i][i] = arr[i];
}
for(int i=arr.length-1;i>=0;i--){
for(int j=i;j<arr.length;j++){
if(i==j){
f[i][j] = arr[i];
}else{
f[i][j] = Math.max(arr[i]+s[i+1][j],arr[j]+s[i][j-1]);
s[i][j] = Math.min(f[i+1][j],f[i][j-1]);
}
}
}
return Math.max(f[0][arr.length-1],s[0][arr.length-1]);
}
public static int f(int[] arr,int l,int r){
if(l==r) return arr[l];
return Math.max(arr[l]+s(arr,l+1,r),arr[r]+s(arr,l,r-1));
}
public static int s(int[] arr,int l,int r){
if(l==r) return 0;
return Math.min(f(arr,l+1,r),f(arr,l,r-1));
}
}