lintcode coins-in-a-line-ii 硬币排成线ii

问题描述

笔记

设置buff[i]为考虑第i个到最后一个硬币,先手的人能拿到的硬币最大价值和对手的硬币最大价值。sum[i]为第i个到最后一个硬币的总价值。

那么,当前情况我可以拿1个或者2个。
1. 拿1个,我先得到values[i]的价值,对方就得到buff[i+1]的价值,我就再得到sum[i+1]-buff[i+1]的价值;
2. 拿2个,我先得到values[i]+values[i+1]的价值,对方得到buff[i+2]的价值,我再得到sum[i+2]-buff[i+2]的价值。
3. 那我肯定取这两者的最大值。

状态转移方程:

buff[i] = max((values[i] + (sum[i+1] - buff[i+1]), values[i]+values[i+1]+sum[i+2]-buff[i+2])

注意

又用到了从后往前算的小技巧!要记住这个小技巧!

代码

class Solution {
public:
    /**
     * @param values: a vector of integers
     * @return: a boolean which equals to true if the first player will win
     */
    bool firstWillWin(vector<int> &values) {
        // write your code here
        const int len = values.size();
        if (len == 1 || len == 2)
            return true;
        vector<int> buff(len, 0);
        vector<int> sum(len, 0);
        buff[len-1] = values[len-1];
        sum[len-1] = values[len-1];
        buff[len-2] = values[len-1] + values[len-2];
        sum[len-2] = buff[len-2];
        for (int i = len-3; i >= 0; i--)
        {
            sum[i] = sum[i+1] + values[i];
            buff[i] = max(values[i]+sum[i+1]-buff[i+1], values[i]+values[i+1]+sum[i+2]-buff[i+2]);
        }

        return (buff[0] > (sum[0]-buff[0]));
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值