有 n 个不同价值的硬币排成一条线。两个参赛者轮流从左边依次拿走 1 或 2 个硬币,直到没有硬币为止。计算两个人分别拿到的硬币总价值,价值高的人获胜。
请判定 第一个玩家 是输还是赢?
样例 给定数组 A = [1,2,2], 返回 true.
给定数组 A = [1,2,4], 返回 false.
这道题运用动态规划来解决。 dp[i] 表示从i到end 能拿到的最大值 一个明显的情况就是当len<=2时,这时候第一个拿的只要全拿走就行了,所以肯定是第一个人赢。然后我们分析
public class Solution {
/**
* @param values: an array of integers
* @return: a boolean which equals to true if the first player will win
*/
public boolean firstWillWin(int[] values) {
// write your code here
// dp 表示从i到end 的最大值
// int values[] ={1,2,4,3,4,8,5,6,12};
int len = values.length;
int[] dp = new int[len+1];
if(len<=2)
return true;
dp[len] = 0;
dp[len-1] = values[len-1];
dp[len-2] = values[len-2] + values[len-1];
dp[len-3] = values[len-3] + values[len-2];
for(int i = len-4;i>=0;i--) {
dp[i] = Math.max(values[i]+Math.min(dp[i+2],dp[i+3]), values[i]+values[i+1]+Math.min(dp[i+3], dp[i+4]));
}
int sum=0;
for(int a:values)
sum+=a;
return dp[0] > sum-dp[0];
}
}