【UVA751】Triangle War
题目链接1: https://www.luogu.com.cn/problem/UVA751
题目链接2: https://www.luogu.com.cn/jump/uva/751
前言
最近看R在玩某树来做黑白棋AI,让我也想学习博弈相关内容。然后学了max-min策略,然后又学了alpha-beta剪枝。
这个题是练习max-min策略+alpha-beta剪枝的好题,但是我们也可以记忆化搜索。
并且此题状态少,记忆化只需要20ms,比用alpha-beta剪枝的做法要快一些。
分析
当然我做这道题还是想学习alpha-beta剪枝的,使用此算法的题解已有,所以不多加解释。
此题有两种max-min策略的解法,解法1是最大最小化最终胜负(1为先手胜利,-1为后手胜利),解法2是最大最小化最终得分差(先手得分-后手得分),当然流程就是先手最大化此值,后手最小化此值。
至于局面的存储,与已有题解类似,存储边的编号,然后用二进制表示已连接的边。而三角形连接我们就手写一个数组表示需要哪三条边(很麻烦)。这个题只有单位三角形得分,似乎题意里没说。
再来说两种解法的差异,因为最终胜负在一方大于等于5分就可判定,所以解法1效率较高,并且我们还可用使用alpha-beta剪枝来优化。
当然我们也可以用解法2。有一个显然的结论,无论此步是A还是B,一个状态只会对应一个最优得分。那么就可以使用记忆化,已知状态总共有$(1 << 18) - 1$种,这样效率就高了。并且我们每组数据前不需要清空记忆化数组,因为一个状态对应一个分数,并不需要知道你是如何到达此状态的。
实现时先模拟给出的N步,然后记录双方已得分数。然后max_min搜索,如果此步得分,继续操作,如果此步不得分,就让对手操作,然后减去对手操作的分数,如果全部连接就返回0,每层都是最大化自己的得分。至于为什么双方都是最大化,我给出以下解释:A最大化(A的得分-B的得分),B最大化(B的得分-A的得分),所以都是最大化。
在最终判定胜负时,设当前玩家为p(p为0或1),若p已得分数+max_min(从p开始)的结果>(p^1)的分数就判定p胜利,否则(p^1)胜利。
代码
解法1
1 | #include <iostream> |
解法2
1 | #include <iostream> |
后记
不过这个题3s时限怕是有点水了。
然后还可以做 【九省联考2018】一双木棋chess,也可以使用max-min策略+记忆化搜索。