题目
给定一个整型数组arr,代表数值不同的纸牌排成一条线。玩家A和玩家B依次拿走每长纸牌,规定玩家A先拿,玩家B后拿,但是每个玩家每次只能拿走最左或者最右的纸牌,玩家A和玩家B都绝顶聪明。请返回最后获取胜者的分数。
暴力递归的方法。定义递归函数f(i,j),表示如果arr[i..j]这个排列上的纸牌被绝顶聪明的人先拿,最终能获得什么分数。定义递归函数s(i,j),表示如果arr[i..j]这个排列上的纸牌被绝顶聪明的人后拿,最终能获得什么分数。
public int win1(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 int f(int[] arr,int i,int j){
if(i==j){
return arr[i];
}
return Math.max(arr[i] + s(arr,i+1,j),arr[j] + s(arr,i,j-1));
}
public int s(int[] arr,int i,int j){
if(i==j){
return 0;
}
return Math.min(f(arr,i+1,j),f(arr,i,j-1));
}
public int win2(int[] arr){
if(arr == null || arrr.length == 0){
return 0;
}
int[][] f = new int[arr.length][arr.length];
int[][] s = new int[arr.length][arr.length];
for(int j = 0;j<arr.length;j++){
f[j][j] = arr[j];
for(int i = j - 0;j >= 0;i--){
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]);
}
}