博弈论板子

这篇博客探讨了三种不同的博弈问题:巴什博弈、Fibonacci博弈和SG打表。在巴什博弈中,分析了最后取石子者的胜败状态。Fibonacci博弈关注的是必败态和必胜态的判断。SG打表则涉及更复杂的策略计算,通过DFS实现。这些博弈问题展示了算法在解决策略和决策问题时的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

巴什博弈(取石子)//最后取,胜

if (n % (p + q) == 0)//p为最少取,q为最多取
{
    printf("second\n"); //必败态
}
else
{
    printf("first\n"); //必胜态
}

巴什博弈(取石子)//最后取,败

while (scanf("%lld%lld%lld", &n, &p, &q) != EOF) //n总数,p最小,q最大
{
    m = n % (p + q);
    if (m == 0)
        m = p + q;
    if (m <= p)
    {
        printf("LOST\n");
    }
    else
    {
        printf("WIN\n");
    }
}

Fibonacci博弈

f[1] = f[2] = 1;
for (ll i = 3; i <= 46; i++)//int范围
{
    f[i] = f[i - 1] + f[i - 2];
}
while (scanf("%lld", &n) != EOF, n)
{
    flag = 0;
    for (ll i = 3; i <= 46; i++)
    {
        if (n == f[i])
        {
            flag = 1;
            break;
        }
    }
    if (flag)
    {
        printf("Second win\n");//必败态
    }
    else
    {
        printf("First win\n");//必胜态
    }
}

SG打表

bool sg[maxn][maxn];

inline void getSg(int x, int y)
{
    for (int upx = 1;; upx++)
    {
        if (upx + x > 5000 && upx + y > 5000)
            return;
        for (int upy = 0;; upy++)
        {
            int up = upx * upy;
            if (up + y > 5000 && up + x > 5000)
                break;
            if (up + y <= 5000 && upx + x <= 5000)
            {
                sg[x + upx][y + up] = 1;
                sg[y + up][x + upx] = 1;
            }
            if (y + upx <= 5000 && x + up <= 5000)
            {
                sg[y + upx][x + up] = 1;
                sg[x + up][y + upx] = 1;
            }
        }
    }
}

for (int i = 0; i <= 5000; i++)
{
    for (int j = 0; j <= i; j++)
    {
        if (!sg[i][j])
            getSg(i,j);
    }
}

DFS打表

//注意 S数组要按从小到大排序 SG函数要初始化为-1 对于每个集合只需初始化1遍
//n是集合s的大小 S[i]是定义的特殊取法规则的数组
int s[110],sg[10010],n;
int SG_dfs(int x)
{
    int i;
    if(sg[x]!=-1)
        return sg[x];
    bool vis[110];
    memset(vis,0,sizeof(vis));
    for(i=0;i<n;i++)
    {
        if(x>=s[i])
        {
            SG_dfs(x-s[i]);
            vis[sg[x-s[i]]]=1;
        }
    }
    int e;
    for(i=0;;i++)
        if(!vis[i])
        {
            e=i;
            break;
        }
    return sg[x]=e;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值