首页 > 其他分享 >「博弈dp」棋盘游戏

「博弈dp」棋盘游戏

时间:2022-12-30 18:57:13浏览次数:42  
标签:状态 博弈 游戏 int 右上角 dp 棋盘 输入

本题为12月30日22寒假集训每日一题题解

题目来源:(未知)

题面

题目描述

懒羊羊和小灰灰在玩一种棋盘游戏,棋盘的尺寸为n个方格*m个方格。一开始在棋盘的右上角(1,m)放一枚硬币,每次一个人可以将硬币向左、下或左下的方格移动。

当某个人无法再移动硬币了,那么这个人就输了。游戏总是懒羊羊先开始,如果他们两个每步都是最优策略,则谁将赢得游戏?

输入

输入包含多组测试数据。每组输入两个整数n和m(0< n, m <=2000)。
当n = m = 0时,输入结束。

输出

对于每组输入,如果懒羊羊赢,输出“Wonderful!”,否则输出“What a pity!”。

样例输入 Copy

5 3
5 4
6 6
0 0

样例输出 Copy

What a pity!
Wonderful!
Wonderful!

思路分析

显然此题直接按照博弈论的基础做法——动态规划即可完成.

在博弈论问题中,状态即为当前规模问题的胜负情况(每次每方操作,都会缩小问题的规模,同时交换先后手),状态转移方程即为游戏的规则,不过由于先后手交换需要取反.由于先手无法移动的状态只可能是左下角的那个格子,所以我们可以将其定义为初始状态,然后从这个状态开始,反推回右上角的格子即可.右上角格子的状态即为当前游戏的结果是胜是负.这里注意是多组输入,每组输入dp数组需要重新初始化.

参考代码

#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3, "Ofast", "inline")

#include <iostream>
#include <vector>
#include <cstring>

using namespace std;

bool dp[2010][2010] = {0}; // 状态转移用数组,记录每个状态先手的胜负情况

int main()
{
    ios::sync_with_stdio(false);

    int n, m;

    while (cin >> n >> m && n != 0)
    {
        memset(dp, 0, sizeof(dp)); // 重置dp数组

        // 从左下角的格子开始状态转移
        for (int i = n - 1; i >= 0; i--)
        {
            for (int j = 0; j < m; j++)
            {
                // 当前状态能由其左、下、左下三个状态转移得到,只要一个状态为真,当前状态即为真.注意每次转移由于先后手转换,需要取反,同时要验证是否越界
                if (i < n - 1)
                {
                    dp[i][j] |= !dp[i + 1][j];
                }
                if (j > 0)
                {
                    dp[i][j] |= !dp[i][j - 1];
                }
                if (i < n - 1 && j > 0)
                {
                    dp[i][j] |= !dp[i + 1][j - 1];
                }
            }
        }

        if (dp[0][m - 1]) // 右上角的初始状态即代表当前游戏是胜是负
        {
            cout << "Wonderful!\n";
        }
        else
        {
            cout << "What a pity!\n";
        }
    }

    return 0;
}

"正是我们每天反复做的事情,最终造就了我们,优秀不是一种行为,而是一种习惯" ---亚里士多德

标签:状态,博弈,游戏,int,右上角,dp,棋盘,输入
From: https://www.cnblogs.com/geministar/p/zstu22_12_30.html

相关文章

  • Codeforces 891 A. Pride 做题记录(DP)
    原题链接:https://codeforces.com/problemset/problem/891/A一个比较显然的性质是如果序列的总$gcd$不为$1$,那么肯定是不存在解的。因为不管怎么样,都有一个因子无......
  • 检测TCP/UDP端口的连通性
    1.TCP端口的连通性TCP端口的连通性,一般通过telnet检测,命令格式如下:telnet<targetHost><targetPort>如果出现以下内容,则表示TCP端口连通性是OK的:[root@localhost~......
  • WordPress右侧边栏添加彩色标签
    摘要玩WordPress建博客的朋友都知道标签的重要性,虽然知更鸟的Begin主题自动了非常不错的3D动态标签,不过仍然有人喜欢静态的标签,不过我今天给大家推荐的《右侧边栏添加彩色标......
  • WordPress首页弹窗美化
    WrodPress美化:给知更鸟主题添加重要公告首页弹窗提示功能步骤如下:1、代码下载首先下载几个代码文件,分别按要求上传到自己主题的相应目录下:notice.css(上传到你主题CSS目录......
  • WordPress正文添加您最近看过的功能
    让网站记住读者的浏览历史,让读者很方便地知道他最近阅读了你博客的哪些文章。这一举措,对于提高用户体验应该是不错的方法。那么,如何为你的WordPress站点添加这个功能?一起往......
  • 彻底关闭WordPress自动更新和后台更新检查
    WordPress的后台更新检测和自动更新功能,由于WordPress更新服务器在国外,而国内的网络由于总总原因总是无法顺畅得连接上WordPress的更新服务器,所以一直卡在那里,造成WordPres......
  • LAMP环境搭建WordPress自动化安装脚本
    此脚本是LAMP环境安装WordPress脚本,有需要朋友可以参考,脚本内容如下:系统环境:CentOS7.4软件版本:Apache:2.4.28Mysql:5.7.29PHP:7.3.7WordPress:5.4[root@localhost~]#vimauto......
  • WordPress添加支付宝第三方登录功能
    OpenSocial操作简单适用范围广;可操作性强;无第三方平台、无接口文件冗余;功能特点社交登陆:腾讯QQ、微博、微信、豆瓣、谷歌、微软、Facebook、Twitter、Github等社交分享:QQ......
  • WordPress添加百度第三方登录功能
    OpenSocial操作简单适用范围广;可操作性强;无第三方平台、无接口文件冗余;功能特点社交登陆:腾讯QQ、微博、微信、豆瓣、谷歌、微软、Facebook、Twitter、Github等社交分享:QQ......
  • VTK_Learning_体绘制讨论_光照&阴影、VTKLODProp3D
    1.光照与阴影通过VTKVolumeProperty可以设置体绘制阴影效果(Shading)。阴影效果主要受环境光系数、散射光系数、反射光系数和高光强度四个参数影响。vtkVolumeProperty::SetAm......