HDU 4701 GAME
2016-07-15 22:52
197 查看
正推:
很有意思,很好的一个题目。
题目的意思是两个人初始状态分别有A和B元,现在有N件可买的商品。两人轮流买,商品必须从左到右买过去,一次可以买若干个。第一个无法买到商品的人输。
一看就知道是博弈题目,但是这并不是什么模型式的博弈题目,其实是转化成递推来做的。
其实这个问题应该是这样来考虑的。
首先告诉了你两个人初始的钱数,那么总共的钱数是确定。在买完若干件商品后,一部分的钱数已经花在了买商品上面(先不管是谁买的),另一部分的钱还分别留在两个人的手中。这样如果我们知道当前买完了某件商品后其中一个人的剩余的钱数,那么我们可以根据总钱数不变来推出另一个人手中的钱数。
同时,如果在买某一件商品开始是,ALICE手中只要有x元就有了必胜的策略,那么他手中的钱数如果大于x,显然就也是必胜咯。
有了这两点,我们可以来个递推,解决这个问题。
状态f[i]表示在买第i件商品前,只要先手的人的钱数不少于f[i],那么他就有必胜的策略。
什么意思呢?
我们首先看看,A+B即总钱数,最多能买到多少件商品,显然后面的商品都是没有用的。
然后,对于可买的最后的那件商品n,f
=a
; 因为根据总钱数,只要他能够买掉最后一件商品,下一个人一定无钱购买后面的商品。
接下来就是从i递推到i-1了。
首先从i-1到i可能有两种情况:
一、第i-1个商品和第i个商品是同一个人购买,这说明要是在购买i-1个商品的时候就有必胜的策略,那么此时他手里的钱数必须不小于a[i-1]+f[i](买完第i-1个商品后,必须至少还剩下f[i]的钱)。
二、第i-1个商品和第i个商品不是同一个人购买,这说明前一个人在购买了i-1个商品后,留下了一个必败态给下一个人去购买第i个商品,这里我们知道对于第i个商品,其必败态就是钱数不足f[i]。这样根据总价值的关系就可以推出这种情况下的f[i-1]了。
综合上面的两种情况,我们知道f[i]就是两种情况中的最小值。
这样逐一递推,到达求出f[1],显然我们只要把f[1]和A比较大小,就可以得出谁胜谁负了。
题目很有意思,以前没做过这种类型的题目。赞一个。
逆推:
思路:Alice和Bob得金币总和为all,然后找到第一个前缀和大于all的数,这个位置是不可能到达的点。
eg:alice有10金币,bob有10金币,则all=20金币,共有5个商品5,6,7,8,9。这样的话第四个点8是不可能到达的,因为到那里需要26金币。
所以找到这个点之后我们要从他前面这个点开始往前递推,可以通过dp,dp[i]就表示到达i这个点时必胜需要多少个金币
还是这个样例eg:alice有10金币,bob有10金币,则all=20金币,共有5个商品5,6,7,8,9。
从第三个位置开始,显然dp[3]=7,因为只要能买得起这个商品,就是必胜,第四个点时无法到达的。
对于第二个位置,要获得必胜,有两种决策:
决策1:直接到达后继的必胜态。即dp[2]=6+dp[3]=13;
决策2:留给对手一个必败态,即对手下一次最多只能有(dp[3]-1)=6个金币,当前有all-5=15个金币,则dp[2]=15-6=9;
两者取较小值,即dp[2]=9;
对于第一个位置,同样的,有两种决策:
决策1:直接到达后继的必胜态。即dp[1]=5+dp[2]=14;
决策2:留给对手一个必败态,即对手下一次最多只能有(dp[2]-1)=8个金币,当前有all=20个金币,则dp[1]=20-8=12;
取较小值,dp[1]=12;
得到了dp[1]后,只需要比较dp[1]和Alice的金币大小即可,alice的金币>=dp[1]时,alice必胜,否则必败。ect:这里10<dp[1],所以alice必败。
很有意思,很好的一个题目。
题目的意思是两个人初始状态分别有A和B元,现在有N件可买的商品。两人轮流买,商品必须从左到右买过去,一次可以买若干个。第一个无法买到商品的人输。
一看就知道是博弈题目,但是这并不是什么模型式的博弈题目,其实是转化成递推来做的。
其实这个问题应该是这样来考虑的。
首先告诉了你两个人初始的钱数,那么总共的钱数是确定。在买完若干件商品后,一部分的钱数已经花在了买商品上面(先不管是谁买的),另一部分的钱还分别留在两个人的手中。这样如果我们知道当前买完了某件商品后其中一个人的剩余的钱数,那么我们可以根据总钱数不变来推出另一个人手中的钱数。
同时,如果在买某一件商品开始是,ALICE手中只要有x元就有了必胜的策略,那么他手中的钱数如果大于x,显然就也是必胜咯。
有了这两点,我们可以来个递推,解决这个问题。
状态f[i]表示在买第i件商品前,只要先手的人的钱数不少于f[i],那么他就有必胜的策略。
什么意思呢?
我们首先看看,A+B即总钱数,最多能买到多少件商品,显然后面的商品都是没有用的。
然后,对于可买的最后的那件商品n,f
=a
; 因为根据总钱数,只要他能够买掉最后一件商品,下一个人一定无钱购买后面的商品。
接下来就是从i递推到i-1了。
首先从i-1到i可能有两种情况:
一、第i-1个商品和第i个商品是同一个人购买,这说明要是在购买i-1个商品的时候就有必胜的策略,那么此时他手里的钱数必须不小于a[i-1]+f[i](买完第i-1个商品后,必须至少还剩下f[i]的钱)。
二、第i-1个商品和第i个商品不是同一个人购买,这说明前一个人在购买了i-1个商品后,留下了一个必败态给下一个人去购买第i个商品,这里我们知道对于第i个商品,其必败态就是钱数不足f[i]。这样根据总价值的关系就可以推出这种情况下的f[i-1]了。
综合上面的两种情况,我们知道f[i]就是两种情况中的最小值。
这样逐一递推,到达求出f[1],显然我们只要把f[1]和A比较大小,就可以得出谁胜谁负了。
题目很有意思,以前没做过这种类型的题目。赞一个。
逆推:
思路:Alice和Bob得金币总和为all,然后找到第一个前缀和大于all的数,这个位置是不可能到达的点。
eg:alice有10金币,bob有10金币,则all=20金币,共有5个商品5,6,7,8,9。这样的话第四个点8是不可能到达的,因为到那里需要26金币。
所以找到这个点之后我们要从他前面这个点开始往前递推,可以通过dp,dp[i]就表示到达i这个点时必胜需要多少个金币
还是这个样例eg:alice有10金币,bob有10金币,则all=20金币,共有5个商品5,6,7,8,9。
从第三个位置开始,显然dp[3]=7,因为只要能买得起这个商品,就是必胜,第四个点时无法到达的。
对于第二个位置,要获得必胜,有两种决策:
决策1:直接到达后继的必胜态。即dp[2]=6+dp[3]=13;
决策2:留给对手一个必败态,即对手下一次最多只能有(dp[3]-1)=6个金币,当前有all-5=15个金币,则dp[2]=15-6=9;
两者取较小值,即dp[2]=9;
对于第一个位置,同样的,有两种决策:
决策1:直接到达后继的必胜态。即dp[1]=5+dp[2]=14;
决策2:留给对手一个必败态,即对手下一次最多只能有(dp[2]-1)=8个金币,当前有all=20个金币,则dp[1]=20-8=12;
取较小值,dp[1]=12;
得到了dp[1]后,只需要比较dp[1]和Alice的金币大小即可,alice的金币>=dp[1]时,alice必胜,否则必败。ect:这里10<dp[1],所以alice必败。
相关文章推荐
- hdu4497 正整数唯一分解定理应用
- QT,QT SDK, QT Creator 区别
- 关于Android开发过程用到的工具类
- GMS认证之CtsVerifier测试
- 递归实现迷宫求解
- java基础笔记很实用
- 8086 CPU 寄存器简介
- 机器学习实战 - 读书笔记(06) – SVM支持向量机
- 第1个linux命令——echo
- 19.Which two statements about the background process of the database writer are true? (Choose two.)
- nginx 配置虚拟目录并支持php
- Linux下安装ncurces
- 美图功能ios源代码
- SQL
- 训练第六天
- Hangman Judge
- PHP Calendar API方法归纳总结
- Socket
- 堆(heap)排序算法
- LRU Cache