递归5

125 阅读1分钟

给定一个整型数组arr,代表数值不同的纸牌排成一条线,

玩家A和玩家B依次拿走每张纸牌

规定玩家A先拿,玩家B后拿,

但是每个玩家每次只能拿走最左或最右的纸牌,

玩家A和玩家B都绝顶聪明,请返回最后获胜者的分数。

分析:这是一个典型的范围上尝试的模型

arr范围L-R
先手的:有两种情况,选择L,那么在L+1,R范围上后手,选择R,那么在L-R-1范围上后手,取两种情况的最大值,如果只有一个数,你先手,直接获得
后手的:有两种情况,如果对面先手选择了L,那么在L+1,R范围上先手,如果对面选择R,那么在L-R-1范围上先手,取两种情况的最小值,对面不会把最大值给你的哈哈,如果只有一个数,你后手,获得不了

代码:

public class Class1 {
    public static void main(String[] args) {
        int[] arr = {1,100,1};
        int i = process1(arr, 0, arr.length - 1); //后手
        int process = process(arr, 0, arr.length - 1);
        System.out.println("i = " + i);;
        System.out.println("process = " + process);
        System.out.println(Math.max(i,process));
    }
    //在L-R上先手拿的最优解
    private static int process(int[] values,int L,int R){
        if(L == R){//先手只剩下一张牌,拿走
            return values[L];
        }

        return Math.max(values[L]+process1(values,L+1,R),values[R]+process1(values,L,R-1));
    }
    //在L-R上后手拿的最优解
    private static int process1(int[] values,int L,int R){
        if(L == R){//后手只剩下一张牌,没得拿
            return 0;
        }
        return Math.min(process(values,L+1,R),process(values,L,R-1));
    }
}