动态规划
/**
* 有一排正数,玩家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中的一个,…
* @param arr[] 数组 i数组第一个 j数组第二个
*/
解题思路
Coding
package com.cy.work01;
public class Mycode {
/**
* 暴力算法 --> 动态规划
*
* @param arr
* @return
*/
public static int my_way(int[] arr) {
//如果数组为空 直接返回
if (arr == null || arr.length == 0) {
return 0;
}
//如果数组不为空 则计算出总分 总分用来比较先行者的分数和后行者的分数
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
}
//计算先发者的分数 启动先行者拿的分数是从数组两侧第一个进行拿取 i,j表示数组两侧的下标
int first_point = first(arr, 0, arr.length - 1);
return Math.max(sum - first_point, first_point);
}
private static int first(int[] arr, int i, int j) {
//判断数组的长度
if (i == j) {
return arr[i];
}
if (i + 1 == j) {
return Math.max(arr[i], arr[j]);
}
return Math.max(
//当先行者取最左边的数时 i为最左边 则下次拿到肯定是最小的
arr[i] + Math.min(first(arr, i + 2, j), first(arr, i + 1, j - 1)),
//所以拿到的小值的那个也为先发者拿到的
arr[j] + Math.min(first(arr, i + 1, j - 1), first(arr, i, j - 2))
);
}
}