您的位置:首页 > 其它

纸牌博弈问题

2017-12-16 10:47 169 查看
【题目】

给定整型数组arr,代表数值不同的纸牌排成一条线。两个玩家AB依次拿走每张纸牌,规定A先拿,B后拿,但每次只能拿走最左边或最右边的纸牌,两人都决定聪明。

请返回最后获胜者的分数。

【举例】

arr=[1,2,100,4]

A拿走1,B拿走2或4,A拿100,返回101

arr=[1,100,2]

A拿1或2,B拿100,返回100

public static void main(String[] args) {
System.out.println(win1(new int[]{1,100,2}));//100
System.out.println(win1(new int[]{1,2,100,4}));//101

System.out.println(win2(new int[]{1,100,2}));//100
System.out.println(win2(new int[]{1,2,100,4}));//101
}


【代码】

//纸牌博弈问题
public static 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 static int f(int[] arr,int i,int j){
//纸牌被聪明人先拿,获得的分数
if(i==j){
return arr[i];
}
//拿走一张(i或者j)后,聪明人成了后拿的人,在两种决策中选最优
return Math.max(arr[i]+s(arr,i+1,j),arr[j]+s(arr,i,j-1));
}

publ
4000
ic static int s(int[] arr,int i,int j){
//纸牌被聪明人后拿,获得的分数
if(i==j){
return 0;
}
//对方拿走一张(i或者j)后,聪明人成了先拿的人,对方也是聪明人,会留下最差的情况
return Math.min(f(arr,i+1,j),f(arr,i,j-1));
}

public static int win2(int[] arr){
if(arr==null||arr.length==0){
return 0;
}
int[][] f=new int[arr.length][arr.length];//表示函数f(i,j)的返回值
int[][] s=new int[arr.length][arr.length];//表示函数s(i,j)的返回值
for(int j=0;j<arr.length;j++){
f[j][j]=arr[j];
for(int i=j-1;i>=0;i--){
f[i][j]=Math.max(arr[i]+s(arr,i+1,j),arr[j]+s(arr,i,j-1));
s[i][j]=Math.min(f(arr,i+1,j),f(arr,i,j-1));
}
}
return Math.max(f[0][arr.length-1], s[0][arr.length-1]);
}


【说明】

方法一暴力回归,好理解,时间复杂度O(2^N),额外空间复杂度O(N)

方法二动态规划,不太明白,时间复杂度O(N^2),额外空间复杂度O(N^2)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: