LintCode 395: First Will Win 2

题目描述

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

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

样例

给定数组 A = [1,2,2], 返回 true.

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

Sat Feb 26 2017

思路

一般这种博弈的题目都是假设双方足够聪明,能够用最优的策略取得胜利的,看似很麻烦,实际上却简化了问题,因为这样的话每一个状态都确定了。

看起来很像动态规划问题,那么就试试写状态转移方程吧。

设硬币数为 \(n\),令 \(dp[i]\) 为从 \(i\) 到 \(n - 1\) 能获得的最大价值。

显然:

\[dp[n - 1] = values[n - 1]
\]

\[dp[n - 2] = values[n - 1] + values[n - 2]$$ <p align="center">(还剩下两个硬币当然要全部拿完了)</p>
$$dp[n - 3] = values[n - 2] + values[n - 3]$$ <p align="center">(还剩下三个硬币当然要拿两个了)</p>

对于一般情况:

\]

dp[i]\,=\,{\rm max}
\begin{cases}
values[i]\,+\,{\rm min}\{dp[i + 2],\,dp[i + 3]\}, & \text{若本轮拿一个硬币} \\
values[i]\,+\,values[i + 1]\,+\,{\rm min}\{dp[i + 3],\,dp[i + 4]\}, & \text{若本轮拿两个硬币}
\end{cases}

\[
外层的 ${\rm max}$ 表示“我”要选择一个利于自身的方案:到底是拿一个还是两个。

内层的 ${\rm min}$ 表示对手要选择一个不利于“我”的方案。

最后只要看 $dp[0]$ 是否超过硬币总价值的 $1/2$ 即可。

有一个小细节需要注意一下,就是 $dp[n - 4]$ 的情况,如此时拿两个硬笔,那么剩下的两个肯定对手肯定会全都拿了,不会再去权衡博弈了。

### **代码**

```C++
// 硬币排成线 II
bool firstWillWin(vector<int> &values)
{
int n = values.size();
if (n <= 2) return true;
vector<int> dp(n);
dp[n - 1] = values[n - 1];
dp[n - 2] = values[n - 2] + values[n - 1];
dp[n - 3] = values[n - 3] + values[n - 2];
int sum = dp[n - 1] + dp[n - 3];
for (int i = n - 4; i >= 0; --i)
{
int get_one = values[i] + min(dp[i + 2], dp[i + 3]);
int get_two = values[i] + values[i + 1];
if (i != n - 4) get_two += min(dp[i + 3], dp[i + 4]);
dp[i] = max(get_one, get_two);
sum += values[i];
}
return dp[0] > sum / 2;
}
```\]

LintCode 395: First Will Win 2的更多相关文章

  1. LintCode 394: First Will Win

    LintCode 394: First Will Win 题目描述 有n个硬币排成一条线.两个参赛者轮流从右边依次拿走1或2个硬币,直到没有硬币为止.拿到最后一枚硬币的人获胜. 请判定 第一个玩家 是 ...

  2. [LintCode] 395. Coins in a Line 2_Medium tag: Dynamic Programming, 博弈

    Description There are n coins with different value in a line. Two players take turns to take one or ...

  3. lintcode 394. Coins in a Line 、leetcode 292. Nim Game 、lintcode 395. Coins in a Line II

    变型:如果是最后拿走所有石子那个人输,则f[0] = true 394. Coins in a Line dp[n]表示n个石子,先手的人,是必胜还是必输.拿1个石子,2个石子之后都是必胜,则当前必败 ...

  4. [LeetCode] 877. Stone Game == [LintCode] 396. Coins in a Line 3_hard tag: 区间Dynamic Programming, 博弈

    Alex and Lee play a game with piles of stones.  There are an even number of piles arranged in a row, ...

  5. [LeetCode] All questions numbers conclusion 所有题目题号

    Note: 后面数字n表明刷的第n + 1遍, 如果题目有**, 表明有待总结 Conclusion questions: [LeetCode] questions conclustion_BFS, ...

  6. [LeetCode] questions conclusion_ Dynamic Programming

    Questions: [LeetCode] 198. House Robber _Easy tag: Dynamic Programming [LeetCode] 221. Maximal Squar ...

  7. [LintCode]——目录

    Yet Another Source Code for LintCode Current Status : 232AC / 289ALL in Language C++, Up to date (20 ...

  8. leetcode & lintcode for bug-free

    刷题备忘录,for bug-free leetcode 396. Rotate Function 题意: Given an array of integers A and let n to be it ...

  9. leetcode & lintcode 题解

    刷题备忘录,for bug-free 招行面试题--求无序数组最长连续序列的长度,这里连续指的是值连续--间隔为1,并不是数值的位置连续 问题: 给出一个未排序的整数数组,找出最长的连续元素序列的长度 ...

随机推荐

  1. lintcode-511-交换链表当中两个节点

    511-交换链表当中两个节点 给你一个链表以及两个权值v1和v2,交换链表中权值为v1和v2的这两个节点.保证链表中节点权值各不相同,如果没有找到对应节点,那么什么也不用做. 注意事项 你需要交换两个 ...

  2. 关于“问吧APP”问卷调查报告分析与体会

         上周根据我们走廊奔跑队的“问吧APP”项目对本校范围内的学生发放了上百份调查问卷,并对此作出了统计和整理.针对我们项目所提出的问题涉及到的用户信息有性别.年龄.学历.职业.平时上网途径以及对 ...

  3. week1词频统计

    使用java完成对txt格式的英文短片进行字符提取及统计. package nenu.softWareProject; import java.io.*;import java.util.*; pub ...

  4. IDEA设置头注释—自定义author和date

    IDEA设置头注释,自定义author和date的方法如下所示: 去掉波浪线的方式:鼠标选中单词 --> 点击鼠标右键 --> spelling --> save 'xxx' to ...

  5. Webservice开发概念

    一.Web Service基本概念 Web Service由两部分组成 SOAP--Web Service之间的基本通信协议. WSDL--Web Service描述语言,它定义了Web Servic ...

  6. POI操作Excel异常Cannot get a text value from a numeric cell

    控制台抛出异常:java.lang.IllegalStateException: Cannot get a text value from a numeric cell 在java中用POI解析exc ...

  7. IIS部署时failed to execute url 解决方法

    web.config中增加如下节点: <system.webServer>  <validation validateIntegratedModeConfiguration=&quo ...

  8. Vue使用,异步获取日期时间后格式成"/Date(1333245600000+0800)/" 转换成正常格式

    js从后台mvc中日期获取,结果格式成"/Date(1333245600000+0800)/"了,当然不能这样展显给用户了,要转换,方法如下: function data_stri ...

  9. SPAMS:稀疏建模工具箱

    https://chunqiu.blog.ustc.edu.cn/?p=570 http://spams-devel.gforge.inria.fr/index.html 在一篇显著性检测文章:Sal ...

  10. solrCloud源码分析之CloudSolrClient

    CloudSolrClient是solrj提供的客户端与solrCloud交互的类.该类的实例与zookeeper进行通信来确定solrCloud collections中的solr endpoint ...