描述
有 n 个不同价值的硬币排成一条线。两个参赛者轮流从 左边 依次拿走 1 或 2 个硬币,直到没有硬币为止。计算两个人分别拿到的硬币总价值,价值高的人获胜。
请判定 先手玩家 必胜还是必败?
若必胜, 返回 true, 否则返回 false.
题目链接:https://www.lintcode.com/problem/395/
方法一:递归
import java.util.Scanner;
/**
* TODO
*
* @author DELL
* @version 1.0
* @date 2022/2/3 11:59
*/
public class chara {
public static int f(int[] values, int l) {
// write your code here
if(l == values.length - 2){
return values[l] + values[l + 1];
}
if(l == values.length - 1){
return values[l];
}
return Math.max(values[l] + s(values, l + 1), values[l] + values[l + 1] + s(values, l + 2));
}
public static int s(int[] values, int l) {
// write your code here
if(l == values.length - 1 || l == values.length - 2){
return 0;
}
return Math.min(f(values, l + 1), f(values, l + 2));
}
public static void main(String[] args) {
int[] values = {1, 2, 2, 2};
System.out.println((f(values, 0) > s(values, 0)));
}
}
方法二:dp
public class Solution {
/**
* @param values: a vector of integers
* @return: a boolean which equals to true if the first player will win
*/
public boolean firstWillWin(int[] values) {
// write your code here
if(values.length <= 2){
return true;
}
int[] f = new int[values.length];
int[] s = new int[values.length];
f[values.length - 1] = values[values.length - 1];
f[values.length - 2] = values[values.length - 1] + values[values.length - 2];
s[values.length - 1] = 0;
s[values.length - 2] = 0;
for(int i = values.length - 3; i >= 0; i--){
f[i] = Math.max(values[i] + s[i + 1], values[i] + values[i + 1] + s[i + 2]);
s[i] = Math.min(f[i+ 1], f[i + 2]);
}
return f[0] > s[0];
}
}