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. JScript脚本

    这个好强大啊 .fiddler2是部分是用这个语言开发的.

  2. 软工网络15团队作业4-DAY4

    每日立会 昨天的工作. 张陈东芳:sql语句存储商品信息 吴敏烽:调试获取商品信息的方法 周汉麟:根据商品编号来获取商品资料方法调试 林振斌:输出最近浏览记录的方法检查 李智:cookies的检查 全 ...

  3. 【第二周】关于java.util包下的Random类

    1.功能:此类的实例用于生成伪随机数流 2.方法(Random的方法有很多,在此只解释说明我认为比较常用的几个方法) (1)next(int bits):生成下一个伪随机数 (2)nextDouble ...

  4. C++11 锁 lock

    转自:https://www.cnblogs.com/diegodu/p/7099300.html 互斥(Mutex: Mutual Exclusion) 下面的代码中两个线程连续的往int_set中 ...

  5. Mysql 学习之 SQL的执行顺序

    mysql的json查询:                                                                       1.一条普通的SQL SELEC ...

  6. SpringMVC源码剖析(五)-消息转换器HttpMessageConverter

    原文链接:https://my.oschina.net/lichhao/blog/172562 #概述 在SpringMVC中,可以使用@RequestBody和@ResponseBody两个注解,分 ...

  7. dbgrid多选日记

    procedure TForm1.DBGrid1KeyPress(Sender: TObject; var Key: Char); begin then begin DBGrid1.DataSourc ...

  8. [讲解]sql except和intersect运算符(比拟两个或多个select语句的结果并前去非重复值)

    图 1 UNION 中若有重复的行,会被移除,只留下一个 1.简介 EXCEPT和INTERSECT运算符使您可以比较两个或多个SELECT语句的结果并返回非重复值. 2.区别 EXCEPT运算符返回 ...

  9. 【.Net】C#获取Windows系统特殊文件夹的路径

    系统特殊文件夹是包含公共信息的文件夹,如“Program Files”.“Programs”.“System”或“Startup”.特殊文件夹在默认情况下由系统设置,或者由用户在安装 Windows ...

  10. Qt 事件处理机制

    Qt 事件处理机制 因为这篇文章写得特别好,将Qt的事件处理机制能够阐述的清晰有条理,并且便于学习.于是就装载过来了(本文做了排版,并删减了一些冗余的东西,希望原主勿怪),以供学习之用. 简介 在Qt ...