数学基础之博弈论

news2024/11/24 1:20:07

1.移棋子游戏

mex为最小的不存在的自然数

#include<bits/stdc++.h>
using namespace std;
const int N=2e3+10,M=2e4+10;
int h[N],e[M],ne[M],idx;
int n,m,k;
int f[N];
void add(int a,int b)
{
    e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
int sg(int u)//求sg函数
{
    if(f[u]!=-1) return f[u];
    set<int> S;//存集合中的已经有的自然数
    for(int i=h[u];~i;i=ne[i])//枚举所有能到的边
    {
        int j=e[i];
        S.insert(sg(j));//把能到的点的sg值放进集合中
    }
    for(int i=0;;i++)//枚举集合中不存在的最小自然数
        if(S.count(i)==0) return f[u]=i;//返回即可
}
int main()
{
    memset(h,-1,sizeof h);
    memset(f,-1,sizeof f);//初始化为-1表示没有给过值
    scanf("%d%d%d",&n,&m,&k);
    while(m--)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        add(a,b);
    }
    int res=0;//一开始是0,你也可以给1或者其他输,但是判断时对应要改
    while(k--)
    {
        int u;
        scanf("%d",&u);
        res^=sg(u);//异或每个棋子的sg值
    }
    if(res==0) puts("lose");//假如异或后是一开始的res则就输
    else puts("win");
    return 0;
}

2.取石子

结论:在所有堆的石子个数>1的情况下

只要石子数+石子的堆d数-1==b是奇数,那么先手必胜。b是不计算所有个数为1的石子堆得出的。的

b是奇数的情况下一定存在一个偶数后继,是偶数的情况下一定是奇数后继

证明

a是石子为1的堆,b是 石子大于1的堆+堆里是石子总数-1 

 第四个合并a中两个,说明出现的一堆大于1的堆然后b就+1(合并出来的堆)+2(多的两个石子) 

为什么b==0和不等于0的情况影响不一样 因为第一次要先减一个1 后面都不需要

b是 石子大于1的堆+堆里是石子总数-1 

#include<bits/stdc++.h>
using namespace std;
const int N=55,M=50010;
int f[N][M];
int dp(int a,int b)
{
    int &v=f[a][b];
    if(v!=-1) return v;//假如求过
    if(!a) return v=b%2;//假如个数为1的堆是空,则直接返回b是不是奇数
    if(b==1) return dp(a+1,0);//假如b是1了,说明b中最后一堆只有一个数放在a中
    if(a&&!dp(a-1,b)) return v=1;//a中取一个
    if(b&&!dp(a,b-1)) return v=1;//b中取一个或者合并b中两堆
    if(a>=2&&!dp(a-2,b+(b?3:2))) return v=1;//合并一个数的堆,则变成了一个个数为2的堆,加到b中
    if(a&&b&&!dp(a-1,b+1)) return v=1;//合并a b中个一堆
    return v=0;
}
int main()
{
    memset(f,-1,sizeof f);//初始化为-1,表示没用过
    int T;
    scanf("%d",&T);
    while(T--)
    {
        //不用重新初始化因为每次的状态是一样的
        int n;
        scanf("%d",&n);
        int a=0,b=0;
        for(int i=0;i<n;i++)
        {
            int x;
            scanf("%d",&x);
            if(x==1) a++;//假如个数是1个,则一个数的堆++
            else b+=b?x+1:x;//假如b是0,则加1个,反之加x+1个
        }
        if(dp(a,b)) puts("YES");//看看能不能走到必胜态
        else puts("NO");
    }
    return 0;
}

3.取石子游戏

待细补

n堆石子只能取左右堆的石子,可以取任意个>0&&<=堆的总数,没得操作的输

定义一个left[i][j]跟right[i][j],表示在i,j这个状态的左边放多少个棋子可以使先手必败,right也同理

答案就是判断一下left[[2][n]==a[1],假如等于就是先手必败,反之必胜

left[i][j]的推法:

 

#include<bits/stdc++.h>
using namespace std;
const int N=1010;
int n;
int a[N];
int l[N][N],r[N][N];
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        for(int len=1;len<=n;len++)//枚举区间长度
            for(int i=1;i+len-1<=n;i++)//枚举左右l,r
            {
                int j=i+len-1;//左边的j
                if(len==1) l[i][j]=r[i][j]=a[i];//假如长度是1,则左右边直接给相同的石子即可
                else
                {
                    //先求left[i][j]
                    int L=l[i][j-1],R=r[i][j-1],X=a[j];
                    if(R==X) l[i][j]=0;//判断1
                    else if(X<L&&X<R||X>L&&X>R) l[i][j]=X;//判断2和5
                    else if(L>R) l[i][j]=X-1;//判断3
                    else l[i][j]=X+1;//判断4
                    //在求right[i][j]做法一样
                    L=l[i+1][j],R=r[i+1][j],X=a[i];
                    if(L==X) r[i][j]=0;
                    else if(X<L&&X<R||X>L&&X>R) r[i][j]=X;
                    else if(R>L) r[i][j]=X-1;
                    else r[i][j]=X+1;
                }
            }
        if(n==1) puts("1");
        else printf("%d\n",l[2][n]!=a[1]);//判断先手是否不是必败即可
    }
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/4988.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Ubuntu16.04搭建UbertoothOne环境

Ubuntu16.04搭建UbertoothOne环境 【支持原创&#xff0c;转载需经过作者同意&#xff0c;否则追究相关责任】 相关链接 ubertoothone 主页ubertoothone github 环境说明 操作系统&#xff1a;Ubuntu 16.04.3 LTSUbertooth软件版本&#xff1a;ubertooth 2020-12-R1Libbtb…

想要精通算法和SQL的成长之路 - 跳跃游戏系列

想要精通算法和SQL的成长之路 - 跳跃游戏系列前言一. 跳跃游戏二. 跳跃游戏II前言 想要精通算法和SQL的成长之路 - 系列导航 一. 跳跃游戏 原题链接 给定一个非负整数数组 nums &#xff0c;你最初位于数组的第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。…

TCP、UDP API调用(实时聊天)

1. TCP连接 服务器创建ServerSocket&#xff0c;并指定端口进行监听&#xff1b; ServerSocket通过accept()接受用户请求并返回Socket&#xff0c;否则一直处于监听状态&#xff0c;线程阻塞&#xff1b; 客户端创建Socket&#xff0c;需要指定服务器的ip和端口&#xff0c;向服…

OpenGL之纹理映射

1.1 Texture Mapping 1.1.1 在OpenGL编程中&#xff0c;应用纹理主要分为四步&#xff1a; 创建纹理对象&#xff0c;并为它装载一个纹理&#xff1b; glGenTexture(1,&texName); //为每个纹理编号&#xff0c;1代表生成一个编号 glBindTexture(GL_TEXTURE_2D,texNam…

一道题学习node.js中的CRLF注入

前言 这几天刷题遇到在node.js题目中注入CRLF实现ssrf的题目&#xff0c;对于我来说知识听新颖。在此记录一下。 CRLF注入 学习过http请求走私漏洞的师傅对于这个CRLF肯定不会陌生。所谓的CRLF就是回车加换行。常用于http数据包。字段之间用一个CRLF分割&#xff0c;首部和主…

【MySQL篇】约束语法及演示总结(全)

目录 理解约束&#xff1a; 约束语法及添加、删除约束语法&#xff1a; 约束总览&#xff1a; ​1、非空约束 2、唯一约束 3、主键约束 4、默认约束 5、外键约束 案例演示&#xff1a; 加深格式记忆&#xff1a; 理解约束&#xff1a; 约束实际上就是我们对表中数据的…

Redis命令及原理学习(一)

redis介绍 redis 是 Remote Dictionary Service 的简称&#xff1b;也是远程字典服务&#xff1b; 节点 通过tcp与redis建立连接交互请求回应模型 redis是一种内存数据库&#xff1a;数据都在内存中。redis是一种kv数据库&#xff1a; 存储方式操作方式 redis是一种数据结构数…

【访谈】Eotalk Vol.05: API 全生命周期管理,如何解决企业 API 安全问题

Eotalk 是由 Eolink 和各合作方一起发起的泛技术聊天活动&#xff0c;每期我们会邀请一些技术圈内的大牛聊聊天&#xff0c;聊一下关于技术、创业工作、投融资等热点话题。 本期 Eotalk 我们邀请到的嘉宾是来自星阑科技的 CTO 徐越~ &#x1f44f;&#x1f44f; 徐越是一位 90…

红黑树(4万字文章超详细,只为一个目的)

我写这篇文章的主要目的其次才是积累知识,主要是因为我想打一个同学的脸. 事情是这样的.我现在中学嘛,我们班上有一个同学他学了红黑树啊,就一副"不可一世"的样子.在我面前炫耀啊.当时我就想立马打他的脸,可是我有没有实力,所以才学习红黑树学到深夜,写了篇博客.言归…

深度解析:会用Excel,还有必要学Python吗?

前言 某站上有个问题&#xff1a; 我都会用Excel了&#xff0c;还有必要学Python吗&#xff1f; &#xff08;文末送读者福利&#xff09; 这个问题大概率可以说明问这个问题的这位同学目前还没有遇到非Python不可的场景&#xff0c;之所以产生了学Python的念头是因为这两年P…

今日分享:文字转语音软件哪个好

如今已经进入到了一个短视频时代&#xff0c;大家饭后或者闲暇时都会通过刷视频来消磨时间&#xff0c;而部分小伙伴看到一些有趣的内容&#xff0c;也想试着自己制作一下。但众所周知&#xff0c;视频拍摄容易&#xff0c;后期剪辑制作确实异常困难的&#xff0c;有许多道工序…

从boot引导到loader引导完整运行

此文针对该文章对loader引导进行了完善后的完整运行过程。&#xff08;具体细节请参见下文&#xff09; boot引导升级&#xff0c;成功引导运行loader_What’smean的博客-CSDN博客boot引导升级&#xff0c;成功引导运行loaderhttps://blog.csdn.net/weixin_42492218/article/d…

【数据结构】11道LeetCode链表OJ练习

文章目录1. 移除链表元素2. 反转链表3. 链表的中间节点4. 链表中倒数第k个节点5. 合并两个有序链表6. 链表分割7. 链表的回文结构8. 相交链表9. 环形链表10. 环形链表II11. 复制带随机指针的链表补充内容&#xff1a;浅谈顺序表和链表的区别1. 移除链表元素 移除链表元素OJ链接…

扫雷游戏优化详解——c语言实现

文章目录 一、扫雷游戏的简单认识与解释 二、扫雷游戏的代码及思路实现 一、扫雷游戏的思路 1、菜单打印 2、创建扫雷区 3、初始化雷区 4、打印雷区 5、布置雷区 6、排雷 三、扫雷游戏代码的整合 game.h game.c test.c 标题&#xff1a;猜数字小游戏 作者&#xff1a;Ggggg…

你适合考PMP还是软考?两者的区别是否清楚,分别能给你带来什么价值

PMP与软考之间有什么区别&#xff0c;应该考哪个更适合自己&#xff1f; 下面从9个方面给大家简单的介绍做一个对比&#xff0c;希望能帮上忙~ 软考和PMP哪个更适合自己&#xff1f; 01 考试介绍 PMP&#xff1a;PMP是项目管理专业人士资格认证&#xff0c;由美国项目管理协…

腾讯云相同配置8核16G的云服务器和轻量服务器该如何选择?

很多个人或者中小企业用户在选择云服务器的时候&#xff0c;已经确认配置的情况下&#xff0c;去选购的时候发现有出现了轻量应用服务器&#xff0c;那么轻量应用服务器和云服务器又有哪些区别&#xff0c;价格为啥又有那么大的差别&#xff0c;该如何选择呢&#xff1f; 从上边…

SSM框架整合详细教程

目录 1. 什么是SSM&#xff1f; 2. SSM整合的时候容器之间如何访问 3. SSM下面的开发步骤 4. SSM整合时候时容易混乱的知识点 1. 什么是SSM&#xff1f; SSM是对三个框架名字的简写&#xff0c;其中第一个S指的是SpringMVC,第二个S指的是Spring&#xff0c;第三个M指的是M…

项目搭建(七)爱心代码❤网站部署(静态网站)

爱心代码❤网站部署&#xff08;静态网站&#xff09;一、环境基础二、修改Tomcat启动配置三、放置静态网站四、启动Tomcat一、环境基础 如果你已经部署了Apache-Tomcat&#xff0c;恭喜你&#xff0c;你已经完成90%的部署工作 如果没有tomcat&#xff0c;那你先部署tomcat吧 …

4_单机优化(确定性算法,优化框架)

优化框架机器学习的优化框架正则化经验风险最小化优化算法的收敛速率假设条件凸函数定义强凸函数定义光滑函数定义优化算法的分类机器学习的优化框架 正则化经验风险最小化 有监督的机器学习问题&#xff1a; 假设输入输出数据 Sn{(xi,yi);i1,...,n}S_n \left\{(x_i, y_i);…

C++与C语言中的字符串

目录 1、关于c语言中的字符串 &#xff08;1&#xff09;c语言中字符串与字符指针 &#xff08;2&#xff09;字符串结尾 2、关于c中的字符串string &#xff08;1&#xff09;从本质上了解string &#xff08;2&#xff09;c中的字符串转换与关联 &#xff08;3&#x…