返回获胜者的分数

有一排正数,玩家A和玩家B都可以看到。

每位玩家在拿走数字的时候,都只能从最左和最右的数中选择一个。玩家A先拿,玩家B再拿,两人交替拿走所有的数字。

两人都力争自己拿到的数的总和比对方多。请返回最后获胜者的分数。

例如∶5,2,3,4

玩家A先拿,当前他只能拿走5或者4。

如果玩家A拿走5,那么剩下2,3,4。轮到玩家B,此时玩家B可以选择2或4中的一个,如果玩家A拿走4,那么剩下5,2,3。轮到玩家B,此时玩家B可以选择5或3中的一个,…

利用动态规划求解

public static int win1(int[] arr){
	if(arr == null || arr.length == 0){
		retrun 0;
	}
	//返回的是先发或者后发者中的最大值,哪个大哪个就获胜
   int sum = 0;
   for(int i = 0; i < arr.length; i++){
   		sum += arr[i];
   }
   int fValue = f(arr, 0, arr.length - 1);
   return Math.max(fValue, sum - fValue);
}
public static int win2(int[] arr){
	if(arr == null || arr.length == 0){
		retrun 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 - 1; i >= 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]);
		}
	}
}

//先发过程
public static int f(int[] arr, int i, int j){
	//如果只有一个数,因为先发,这个数肯定被我拿了
	if(i == j){
		return arr[i];
	}
	//要么先那arr[i],然后在i + 1-j的范围内后发情况下能获得的收益
	return Math.max(arr[i] + s(arr, i + 1, j), arr[j] + s(arr, i, j - 1));
}
//后发过程
public static int s(int[] arr, int i, int j){
	//如果只有一个数的话,因为后发,这个数我肯定拿不到,所以返回值为0
	if(i == j){
		return 0;
	}
	//剩下两种决策中差的给你,因为最好的选择由不得我
	//如果先发拿走了arr[i],那我就是在i+1,j中先发
	//如果先发拿走了arr[j],那我就是在i,j-1中先发
	return Math.min(f(arr, i + 1, j), f(arr, i, j - 1));
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值