资讯专栏INFORMATION COLUMN

Lintcode Coins in a line II

2shou / 3135人阅读

摘要:两个参赛者轮流从左边依次拿走或个硬币,直到没有硬币为止。计算两个人分别拿到的硬币总价值,价值高的人获胜。请判定第一个玩家是输还是赢样例给定数组返回给定数组返回复杂度思路考虑先手玩家在状态,表示在在第的硬币的时候,这一位玩家能拿到的最高价值。

LintCode Coins in a line II

有 n 个不同价值的硬币排成一条线。两个参赛者轮流从左边依次拿走 1 或 2 个硬币,直到没有硬币为止。计算两个人分别拿到的硬币总价值,价值高的人获胜。

请判定 第一个玩家 是输还是赢?

样例
给定数组 A = [1,2,2], 返回 true.
给定数组 A = [1,2,4], 返回 false.

dp

复杂度
O(N)

思路
考虑先手玩家在状态dp[i],dp[i]表示在在第i的硬币的时候,这一位玩家能拿到的最高价值。
如果先手玩家取一枚硬币,那么dp[i] = values[i] + sum[i + 1] - dp[i + 1]。减去dp[i + 1]的原因是,对手玩家,每次也要想办法拿到最大的价值,所以先手玩家能拿到的价值是在对手玩家拿到最大价值的硬币之后的剩余的硬币价值。

如果先手玩家取两枚,那么dp[i] = values[i] + values[i + 1] + sum[i + 2] - dp[i + 2];

注意判断是否先手玩家赢的条件,是2倍dp[0]的值是不是大于sum[0],应为是要求拿到硬币价值多的玩家算赢。

代码

public boolean firstWillWin(int[] values) {
    int len = values.length;
    int[] sum = new int[len];
    int[] dp = new int[len];
    for(int i = len - 1; i >= 0; i --) {
        if(i == len - 1) sum[i] = values[i];
        else sum[i] = values[i] + sum[i + 1];
    }
    for(int i = len - 1; i >= 0; i --) {
        if(i == len - 1) dp[i] = values[i];
        else if(i == len - 2) dp[i] = values[i] + values[i + 1];
        else {
            dp[i] = Math.max(values[i] + sum[i + 1] - dp[i + 1], values[i] + values[i + 2] + sum[i + 2] - dp[i + 2]);
        }
    }
    return dp[0] * 2 > sum[0];
}
Recursion + Memorization

复杂度
O(N),O(N)

思路
思路是一样,不过是从bottom-up的算法,用map来保存已经搜索过的路线。

代码

Map map = new HashMap<>();
public int helper(int left, int right, int[] values, int[] sum) {
    // Base case;
    if(left > right) return 0;
    if(left == right) return values[left];
    if(left + 1 == right) return values[left] + values[right];
    if(map.containsKey(left)) return map.get(left);
    //
    int val = Math.max(values[left] + sum[left + 1] + helper(left + 1, right, values, sum), values[left] + values[left + 1] + sum[left + 2] + helper(left + 2, right, values, sum));
    map.put(left, val);
    return val;
}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/65257.html

相关文章

  • LintCode Coins in a line III

    摘要:复杂度思路参考的思路,对于,表示在从到的范围内,先手玩家能拿到的最大的硬币价值。对于状态,先手玩家有两种选择,要么拿的硬币,要么拿的硬币左边一个的或者右边一侧的,如果拿左侧的硬币,如果拿右侧的硬币,取两个值的最大值。 LintCode Coins in a line III There are n coins in a line. Two players take turns to ...

    focusj 评论0 收藏0
  • [LintCode] Coins in a Line I &amp; Coins in a Line

    摘要:第一个游戏者永远拿不到第枚硬币,所以在硬币总数不能被整除的情况下,都可以赢。做法,设为第一个游戏者从第枚硬币到能获得硬币价值的最大值。主要参考这篇文章的解释 Coins in a Line I Solution 第一个游戏者永远拿不到第3n枚硬币,所以在硬币总数不能被3整除的情况下,都可以赢。 public class Solution { public boolean fi...

    xzavier 评论0 收藏0
  • Lintcode Coins in a line

    摘要:有个硬币排成一条线。两个参赛者轮流从右边依次拿走或个硬币,直到没有硬币为止。拿到最后一枚硬币的人获胜。表示的是,当有个棋子的时候,先手玩家会不会输。赢得条件是,和的状态是输的状态。 LintCode: coins in a line I 有 n 个硬币排成一条线。两个参赛者轮流从右边依次拿走 1 或 2 个硬币,直到没有硬币为止。拿到最后一枚硬币的人获胜。 请判定 第一个玩家 是输还...

    itvincent 评论0 收藏0
  • [LintCode/LeetCode] Subsets &amp; Subsets II

    Subsets Problem Given a set of distinct integers, return all possible subsets. Notice Elements in a subset must be in non-descending order.The solution set must not contain duplicate subsets. Example ...

    tracy 评论0 收藏0
  • [LintCode/LeetCode] Combination Sum I &amp; II

    摘要:和唯一的不同是组合中不能存在重复的元素,因此,在递归时将初始位即可。 Combination Sum I Problem Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T...

    ThreeWords 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<