博弈

题目:Brave Game

#include<iostream>
using namespace std;
int main()
{
	int c,n,m,i,j;
	cin>>c;
	while(c--)
	{
		cin>>n>>m;
		if(n%(m+1))
		cout<<"first"<<endl;
		else
		cout<<"second"<<endl;
	}
	return 0;
}

巴什博弈:
只有一堆n个物品,两个人轮流从这堆物品中取物,规定每次至少取一个,最多取m个.最后取光者得胜.
如果物品时1~m的话,先手必赢
物品时1+m~2*m的话,不管先手如何取后手必赢
所以如果n=(m+1)任意倍数+s(s<=m)的话先手必赢,因为先手拿掉s的话,就成了奇异局势,不管后手取多少(假设是x),先手只要取m-x-1就一定会使最后石子变成后手面对1+m~2m的局势这样先手必赢,反之后手必赢

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

如果 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,那么后取者必胜。 否则 先取者 必胜。

组合博弈 – 三大基本博弈

经典博弈算法三大模板:

最近研究了一下博弈论(听起来很高大上),当然,这只是博弈论中的冰山一角,但不可否认,巴氏(bash)博弈,威佐夫(Wythoff)博弈和尼姆(Nim)博弈这三种在ACM比赛中也是相当重要的,而最大的问题就是,博弈理解起来有较大的难度,即使理解了,也很难快速转换成代码,这对于做题来说是很不利的,于是,我就决定写一套模板,包括多一点接口,从而方便以后的使用,当然,虽然说是自己写的,但也是参考了别人的代码,所以别告我侵权哈。大笑

首先是Bash(巴氏)博弈,这是比较简单的一种,原理就不解释了,相信大家都懂,代码很简短,只需要输入这一堆石子的数目,输赢立刻见分晓

#include<iostream> 
using namespace std; 
int main(void) 
{ 
    int cas,total,price; 
    scanf("%d",&cas); 
    while(cas--) 
    { 
        scanf("%d%d",&total,&price); 
        if(total%(price+1)) 
            cout<<"先手赢"<<endl; 
        else 
            cout<<"先手输"<<endl; 
    } 
    return 0; 
} 

接下来上威佐夫(Wythoff)博弈,石子变成两堆,难度也大幅提升,但是

#include<iostream>
#include<cmath>
#include<stdio.h>
using namespace std;
int main ()
{
    int a,b,dif;
    double p=(sqrt((double)5)+1)/double(2);
    while(cin>>a>>b)
    {
        dif=abs(a-b);//取差值
        a=a<b?a:b;//取较小的值
        if(a==(int)(p*dif))//判断是不是奇异局势
            printf("0\n");
        else printf("1\n");
    }
    return 0;
}

我擦,为毛代码还是这么短惊恐,大神膜拜中。。。(过奖过奖生气,如有雷同,请相信这真的只是借鉴)

最后奉上尼姆(Nim)博弈,这种博弈其实就是分解成简单的博弈再一一求解

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
using namespace std;
int a[200005],ans[200005][2];
int main()
{
    int n,i,j,cnt,s;
    while(~scanf("%d",&n),n)
    {
        cnt = 0;
        s = 0;
        for(i = 0; i<n; i++)
        {
            scanf("%d",&a[i]);
            s^=a[i];
        }
        for(i = 0; i<n; i++)
        {
            if(a[i] > (s^a[i]))
            {
                ans[cnt][0] = a[i];
                ans[cnt][1] = s^a[i];
                cnt++;
            }
        }
       if(cnt)//判断先手是胜是负
        {
            printf("Yes\n");
            for(i = 0; i<cnt; i++)
                printf("%d %d\n",ans[i][0],ans[i][1]);//输出若先手为胜的走法
        }
        else
            printf("No\n");
            cout<<cnt<<endl;//输出使先手为胜的方案的数目
    }
    return 0;
}

这个稍微长一点,因为里面增加了很多步骤,大大方便了题目的求解。

从今天开始,你就可以骄(zhuang)傲(bi)的说:“今朝获此三模板,从此博弈是水题!”

博弈论具体知识详解:博弈知识汇总

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CSDN IT狂飙上传的代码均可运行,功能ok的情况下才上传的,直接替换数据即可使用,小白也能轻松上手 【资源说明】 基于MATLAB实现的数字调制就是把数字基带信号的频谱搬移到高频处,形成适合在信道中传输的带通信号基本的数字调制方式有振幅键控(ASK)、频移键控(FSK)、绝对相移键控(PSK)、相对(差分)相移键控(DPSK)在接收端可以基于想干解调或非相干解调还原数字基带信号+使用说明文档 1、代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2020b;若运行有误,根据提示GPT修改;若不会,私信博主(问题描述要详细); 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可后台私信博主; 4.1 期刊或参考文献复现 4.2 Matlab程序定制 4.3 科研合作 功率谱估计: 故障诊断分析: 雷达通信:雷达LFM、MIMO、成像、定位、干扰、检测、信号分析、脉冲压缩 滤波估计:SOC估计 目标定位:WSN定位、滤波跟踪、目标定位 生物电信号:肌电信号EMG、脑电信号EEG、心电信号ECG 通信系统:DOA估计、编码译码、变分模态分解、管道泄漏、滤波器、数字信号处理+传输+分析+去噪、数字信号调制、误码率、信号估计、DTMF、信号检测识别融合、LEACH协议、信号检测、水声通信 5、欢迎下载,沟通交流,互相学习,共同进步!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值