博弈学习 1

看完三位博主的文章再做了几个简单题后的简单总结。
可以看原文,比较详细~~

链接 1: http://blog.csdn.net/logic_nut/article/details/4711489
链接 2: http://blog.sina.com.cn/s/blog_83d1d5c70100y9yd.html
链接 3: http://blog.csdn.net/luomingjun12315/article/details/45479073

几个定义与结论:

1)两个状态
P-Position : P 指的是 Previous ,上一次移动的人有必胜策略,即先手必败
N-Position :N 指的是 Next ,这次移动的人有必胜策略,即先手必胜

1. 无法进行任何移动的局面(也就是terminal position)是P-position;
2. 可以移动到P-position的局面是N-position。 也就是说如果一个状态是 P-Position那么能够转移到这个局面的所有局面都是 N-Position
3. 所有移动都导致N-position 的局面是P-position。也就是说它之前的状态中有一个 N-position,就可以确定这个局面是 P-position

这个可以结合链接 1 原文想一想,就不糊涂辣 ~

组合游戏:

1、有且仅有两个玩家
2、两名玩家交替在 有限的移动集合(比如:取石子游戏,石子是有限的,棋盘中的棋盘大小的有限的)中对游戏进行合法的移动(不能不移动)
3、如果轮到某名选手移动,且这个局面的合法的移动集合为空(也就是说此时无法进行移动),则这名选手负。

Nim游戏:
它是组合游戏(Combinatorial Games)的一种,准确来说,属于“Impartial Combinatorial Games”(以下简称ICG)。

通常的Nim游戏的定义是这样的:有若干堆石子,每堆石子的数量都是有限的,
合法的移动是“选择一堆石子并拿走若干颗(不能不拿)”,如果轮到某个人时所有的石子堆都已经被拿空了,则判负(因为他此刻没有任何合法的移动)。

一个结论:
(Bouton‘s Theorem)对于一个Nim游戏的局面(a1,a2,...,an),它是P-position当且仅当a1^a2^...^an=0,其中^表示异或(xor)运算。

证明在链接 1 中~

几个题都是简单的巴什博奕。

巴什博奕(Bash Game):有一堆n个物品,两人轮流从堆中取物品,每次取 x 个 ( 1 ≤ x ≤ m)。最后取光者为胜。

HDU 1846

1) 可以用上述的 P-Position 和 N-Position的定义解,多模拟几次就可以发现规律,然后就可愉快解题了。

例如 n m 分别为 6 2时
即石子有 6 颗,两人轮流取,每次可以可取 1~2 颗 。

那么所有的状态应该是这样的:

有x颗时  0 1 2 3 4 5 6
Position P N N P N N P

发现规律了咩~

2) 也可以这样想 ,复制一段来自链接 3 的推导:

如果 n = m + 1, 一次至多取 m 个,所以无论先取者,取了多少个,一定还剩余 x 个( 1 ≤ x ≤ m)。所以,后取者必胜。
因此我们发现了取胜的秘诀:如果我们把 n 表示为 n = (m + 1) * r + s 。(0 ≤ s < m , r ≥ 0)。
先取者 拿走 s 个, 后取者 拿走 k 个 (1 ≤ k ≤ m),那么先取者 再 拿走 m + 1 - k 个。
结果还剩下 ( m + 1 ) * ( r - 1 ) 个。我们只要始终给对手留下 m + 1 的倍数,那么 先取者 肯定必胜。
现在 我们可以知道,如果 s = 0,那么后取者必胜。 否则 先取者 必胜。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
using namespace std;
int main()
{
    int t,n,m;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&m);
        if(n%(m+1) == 0) printf("second\n");
        else printf("first\n");
    }
    return 0;
}

HDU2147

题意: N*M棋盘,最初棋子在右上角,即(1,M) 每次可以往左、下、左下走一步,最后走到左下角的胜 。

最先开始 把它看做一个类似取石子的游戏,每次可走1~2步的(走到左下算两步= =)

然后 WA 掉了 WA 掉了 掉了 了。。

正解是又照着定义模拟了一遍 ,找出规律,即当 N M 都是奇数的时候先手必败。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
using namespace std;
int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        if(n==0 && m==0) break;
        if((n&1) && (m&1)) printf("What a pity!\n");
        else printf("Wonderful!\n");
    }
    return 0;
}

HDU2188
与 HDU 1846 同理哟

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
using namespace std;
int main()
{
    int t,n,m;
    cin>>t;
    while(t--){
        cin>>n>>m;
        if(n%(m+1)) cout<<"Grass"<<endl;
        else cout<<"Rabbit"<<endl;
    }
    return 0;
}

HDU 2149

按照上面的推导 ,如果我们把 n 表示为 n = (m + 1) * r + s 。(0 ≤ s < m , r ≥ 0)。
那么 s 就是第一次的加价 。如果加价大于本价,也就是说先手可以直接买到了 ,那么出的价就可以是 m~n这一段里的任一。
最先开始自己没想清楚,以为 1~s 都可以,= = 后来想了下,如果不直接加到 S ,那不是给了对方可乘之机 = =

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
using namespace std;
int main()
{
    int t,n,m;
    while(scanf("%d%d",&m,&n)!=EOF){
        if(m%(n+1)){
            int x = m%(n+1);
            if(n>=m){
                cout<<m;
                for(int i=m+1;i<=n;i++) printf(" %d",i);
            }
            else printf("%d",x);
        }
        else printf("none");
        cout<<endl;
    }
    return 0;
}

*/

时间: 2024-10-23 12:07:39

博弈学习 1的相关文章

白书 博弈学习

nim博弈 n堆火柴,每堆有若干个火柴,两人轮流拿,每次可以选择一堆至少拿一个,也可以整堆拿走,无法拿的人输. 每堆火柴的个数异或和==0,先手输,否则先手赢. http://acm.hust.edu.cn/vjudge/problem/32746    UVA11859 题意:给2维矩阵,每次可以选择矩阵的一行中的1个或多个大于1的整数,把他们每个数都变成真因子.  12可以变1 2 3 4 6. 解法: 等价于拿掉一个或者多个素因子,一行对应一堆火柴,每个数每个素因子看成一个火柴,即nim博

hdu4315 Climbing the Hill(阶梯博弈)

Climbing the Hill Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1218    Accepted Submission(s): 548 Problem Description Alice and Bob are playing a game called "Climbing the Hill". The g

nim博弈

原题链接 :https://www.acwing.com/problem/content/893/ 给定nn堆石子,两位玩家轮流操作,每次操作可以从任意一堆石子中拿走任意数量的石子(可以拿完,但不能不拿),最后无法进行操作的人视为失败. 问如果两人都采用最优策略,先手是否必胜. 输入格式 第一行包含整数nn. 第二行包含nn个数字,其中第 ii 个数字表示第 ii 堆石子的数量. 输出格式 如果先手方必胜,则输出“Yes”. 否则,输出“No”. 数据范围 1≤n≤1051≤n≤105,1≤每堆

机器学习术语表

FFNN Feed Forward Neural Network 前馈神经网络,神经网络中一般输入向前传递 BP Backpropagation 反向传播,一般专指误差反向传播算法, RBM Restricted Boltzmann Machine 限制波兹曼机 受限波兹曼机 监督学习 给出data与label 无监督学习 仅有data 强化学习 给出data与响应函数,让机器根据响应函数反馈自行学习 深度学习 一般指神经网络这样拥有深层结构的算法 自博弈学习 一对生成算法和判别算法互相学习,最

转行人工智能,不得不温习的数学知识点

机器学习数学基础 讲师:钱鸿   肖鸿飞 开课时间:2018.8.19   每周六.日晚7-9点 原价:1599     早鸟价:1299 (限前100位报名者) 为什么开这门课? 机器学习是实现人工智能的重要方法,也是推动当下人工智能发展的核心驱动力.深度学习.强化学习.迁移学习都属于机器学习研究领域.机器学习处理实际应用案例时,不是"十八般兵器" 的堆积,而是根据具体任务,按需设计.量身定制,做到这一点就需要我们深刻理解机器学习模型以及算法背后的原理,做到知其然又知其所以然! 数学

ACM学习历程—HDU 3915 Game(Nim博弈 &amp;&amp; xor高斯消元)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3915 题目大意是给了n个堆,然后去掉一些堆,使得先手变成必败局势. 首先这是个Nim博弈,必败局势是所有xor和为0. 那么自然变成了n个数里面取出一些数,使得xor和为0,求取法数. 首先由xor高斯消元得到一组向量基,但是这些向量基是无法表示0的. 所以要表示0,必须有若干0来表示,所以n-row就是消元结束后0的个数,那么2^(n-row)就是能组成0的种数. 对n==row特判一下. 代码:

小小的学习一发博弈

一.  巴什博奕(Bash Game): A和B一块报数,每人每次报最少1个,最多报4个,看谁先报到30.这应该是最古老的关于巴什博奕的游戏了吧. 其实如果知道原理,这游戏一点运气成分都没有,只和先手后手有关,比如第一次报数,A报k个数,那么B报5-k个数,那么B报数之后问题就变为,A和B一块报数,看谁先报到25了,进而变为20,15,10,5,当到5的时候,不管A怎么报数,最后一个数肯定是B报的,可以看出,作为后手的B在个游戏中是不会输的. 那么如果我们要报n个数,每次最少报一个,最多报m个,

[深度学习]实现一个博弈型的AI,从五子棋开始(1)

好久没有写过博客了,多久,大概8年???最近重新把写作这事儿捡起来……最近在折腾AI,写个AI相关的给团队的小伙伴们看吧. 搞了这么多年的机器学习,从分类到聚类,从朴素贝叶斯到SVM,从神经网络到深度学习,各种神秘的项目里用了无数次,但是感觉干的各种事情离我们生活还是太远了.最近AlphaGo Zero的发布,深度学习又火了一把,小伙伴们按捺不住内心的躁动,要搞一个游戏AI,好吧,那就从规则简单.老少皆宜的五子棋开始讲起. 好了,废话就说这么多,下面进入第一讲,实现一个五子棋. 小伙伴:此处省去

B站学习记:贪心与博弈

贪心 1. poj2287 N匹马的田忌赛马问题 稳稳地赢. 寻找最优的方案. 更优的收益. 有时候,局部最优导致全局最优. 马的能力值. 使得让我赢的局数最多. 对于对方的任何一匹马,如果我的马能打败它,那么我就要用能打败它的马里面能力值最小的马去迎战,如果我的马不能打败它,那么我就用剩下的所有马中能力 最小的马去迎战.这个思路是很贪心的. 贪心不是一板一眼的算法,更是一种思路. #include<cstdio>#include<cstring>#include<algor