P4363 [九省联考2018]一双木棋chess

题目描述

菲菲和牛牛在一块\(n\)行\(m\)列的棋盘上下棋,菲菲执黑棋先手,牛牛执白棋后手。 棋局开始时,棋盘上没有任何棋子,两人轮流在格子上落子,直到填满棋盘时结束。

落子的规则是:一个格子可以落子当且仅当这个格子内没有棋子且这个格子的左侧及上方的所有格子内都有棋子。

棋盘的每个格子上,都写有两个非负整数,从上到下第\(i\)行中从左到右第\(j\)列的格子上的两个整数记作\(A_{i,j},B_{i,j}\) 。在游戏结束后,菲菲和牛牛会分别计算自己的得分:菲菲的得分是所有有黑棋的格子上的\(A_{i,j}\)之和,牛牛的得分是所有有白棋的格子上的\(B_{i,j}\)的和。

菲菲和牛牛都希望,自己的得分减去对方的得分得到的结果最大。现在他们想知道,在给定的棋盘上,如果双方都采用最优策略且知道对方会采用最优策略,那么,最终的结果如何。

输入输出格式

输入格式:

输入第一行包含两个正整数\(n,m\),保证\(n,m<=10\)。

接下来\(n\)行,每行\(m\)个非负整数,按从上到下从左到右的顺序描述每个格子上的 第一个非负整数:其中第\(i\)行中第\(j\)个数表示\(A_{i,j}\) 。

接下来\(n\)行,每行\(m\)个非负整数,按从上到下从左到右的顺序描述每个格子上的 第二个非负整数:其中第\(i\)行中第\(j\)个数表示\(B_{i,j}\) 。

输出格式:

输出一个整数,表示菲菲的得分减去牛牛的得分的结果。

说明:


也算是第一次做这样的博弈吧,省选划水的时候没做过状压也没做过博弈。好不容易YY出了\(n+m\)轮廓线处理的方法却不清楚怎么确定最优策略。结果15分的分类讨论分居然因为读入把A,B一起读了而爆0。。

先看看最优策略如何确定的:如果双方都采用最优策略且知道对方会采用最优策略

由此我们得,我们要使用最优策略,首先要知道对方的最优策略,然后才能确定自己的最优策略。

但是如果我们只考虑前面的已经做的状态,是无法得知最优策略的。

这时候我们反其道而行之,把当前一步可以到达的局面看成一个子问题。这个子问题已经产生了答案,它是一个规模缩小版的但已经处理完了每一步的一个游戏。我们这一步可以进入这个子问题,但进入的入口并不唯一,我们对这个不唯一进行决策,找到对自己而言的局面最大化进入。而这个子问题的最小规模又是唯一确定的,也就是最后一步。所以我们的思路是,先通过记忆化搜索进入最后一步,然后像做树形DP那样在对搜索树进行回溯的时候更新答案。

对于两个人的具体策略而言,我们不妨把\(score_a-score_b\)压入转移方程,则\(A\)的目的是求\(score_a-score_b\)极大化,而\(B\)的目的是求\(score_a-score_b\)极小化,这就是\(max-min\)对抗式搜索模型。

我们再来分析一下每一步的状态:一个格子可以落子当且仅当这个格子内没有棋子且这个格子的左侧及上方的所有格子内都有棋子,题目中这样一句话给了我们一个轮廓线描述状态的启示,我们只能在这样的轮廓线上进行,用0描述竖着的轮廓线,用1描述横着的轮廓线,则状态可以被长为\(n+m\)的轮廓线唯一的表示

画图举个例子

轮廓线为1001101

当进行状态转移时,我们模拟一下可以发现,当某位上为1而这一位的更高一位上为0时,当我们把这两位取反就是把轮廓线向外扩张了一个。用轮廓线确定坐标也不难,我们从低位开始枚举,对每一位的0或1决定如何移动当前对应坐标即可


Code:

#include <cstdio>
const int inf=0x3f3f3f3f;
int max(int x,int y){return x>y?x:y;}
int min(int x,int y){return x<y?x:y;}
int n,m,a[12][12],b[12][12],dp[1048578],used[1048578];
void init()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&a[i][j]);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&b[i][j]);
}
int dfs(int s,int who)
{
if(used[s])
return dp[s];
used[s]=1;
dp[s]=who?-inf:inf;
int x=1,y=m,tmp;
for(int i=0;i<n+m-1;i++)
{
if(((s>>i)&1)&&!((s>>i+1)&1))
{
tmp=s^(3<<i);
if(who)
dp[s]=max(dp[s],dfs(tmp,who^1)+a[x][y]);
else
dp[s]=min(dp[s],dfs(tmp,who^1)-b[x][y]);
}
if((s>>i)&1) y--;
else x++;
}
return dp[s];
}
int main()
{
init();
used[(1<<n+m)-(1<<n)]=1;
printf("%d\n",dfs((1<<m)-1,1));
return 0;
}

2018.7.6

洛谷 P4363 [九省联考2018]一双木棋chess 解题报告的更多相关文章

  1. 洛谷 P4363 [九省联考2018]一双木棋chess 题解

    题目链接:https://www.luogu.org/problemnew/show/P4363 分析: 首先博弈,然后考虑棋盘的规则,因为一个子在落下时它的上面和左面都已经没有空位了,所以棋子的右下 ...

  2. 洛谷P4363 [九省联考2018]一双木棋chess 【状压dp】

    题目 菲菲和牛牛在一块n 行m 列的棋盘上下棋,菲菲执黑棋先手,牛牛执白棋后手. 棋局开始时,棋盘上没有任何棋子,两人轮流在格子上落子,直到填满棋盘时结束. 落子的规则是:一个格子可以落子当且仅当这个 ...

  3. luogu P4363 [九省联考2018]一双木棋chess

    传送门 对抗搜索都不会,我真是菜死了qwq 首先根据题目条件,可以发现从上到下每一行的棋子数是单调不增的,然后n m都比较小,如果把状态搜出来,可以发现合法状态并不多,所以可以用一个11进制数表示状态 ...

  4. 【题解】Luogu P4363 [九省联考2018]一双木棋chess

    原题传送门 这道题珂以轮廓线dp解决 经过推导,我们珂以发现下一行的棋子比上一行的棋子少(或等于),而且每一行中的棋子都是从左向右依次排列(从头开始,中间没有空隙) 所以每下完一步棋,棋盘的一部分是有 ...

  5. P4363 [九省联考2018]一双木棋chess

    思路 容易发现只能在轮廓线的拐点处落子,所以棋盘的状态可以用一个n+m长度的二进制数表示 转移就是10变成01 代码 #include <cstdio> #include <algo ...

  6. P4363 [九省联考2018]一双木棋chess(对抗搜索+记忆化搜索)

    传送门 这对抗搜索是个啥玩意儿…… 首先可以发现每一行的棋子数都不小于下一行,且局面可由每一行的棋子数唯一表示,那么用一个m+1进制数来表示当前局面,用longlong存,开map记忆化搜索 然后时间 ...

  7. BZOJ.5248.[九省联考2018]一双木棋chess(对抗搜索 记忆化)

    BZOJ 洛谷P4363 [Update] 19.2.9 重做了遍,感觉之前写的有点扯= = 首先棋子的放置情况是阶梯状的. 其次,无论已经放棋子的格子上哪些是黑棋子哪些是白棋子,之前得分如何,两人在 ...

  8. [九省联考2018]一双木棋chess——搜索+哈希

    题目:bzoj5248 https://www.lydsy.com/JudgeOnline/problem.php?id=5248 洛谷P4363 https://www.luogu.org/prob ...

  9. P4363 [九省联考2018]一双木棋

    题面 这种搜索要把后继状态都跑出来之后取Min/Max 也就是回溯的时候进行操作 记得用hash进行记忆化(用map不开O2会TLE) #include<iostream> #includ ...

随机推荐

  1. 《Redis设计与实现》阅读笔记(一)--Redis学习

    Redis学习资料与过程记录 在实习中经常会用到很多Redis,对Redis有了一些模糊的了解,总觉得隔靴搔痒的不痛快,所以决定开始深入的了解Redis,也作为我实习期间的目标. 这篇只是为了占个位置 ...

  2. Docker 自定义网络

    1.创建自定义网络 docker network create -d bridge --subnet 172.25.0.0/16 network_name 2.redis docker 添加到网络 d ...

  3. windows的滚动条使用

    背景 在毕业快一年的工作时间中,对windows编程的某些特性并不够熟悉,例如滚动条的使用.在一次需求中需要用到滚动条,在开发过程中走了不少弯路,因此需要做一些笔记总结一下学习到的内容. 先推荐几个写 ...

  4. python—启动自带shell时报错(丢失api-ms-win-crt-runtime-l1-1-0.dll)已解决

    备注: 有的伙伴安装完1后重启,问题可以解决,summer儿在安装完1依然未能解决,于是又进行了2的安装再次重启后问题解决!! 1,安装vc-redist.x64,微软官网搜索免费下载,安装后重启. ...

  5. node http模块搭建简单的服务和客户端

    node-http Node.js提供了http模块,用于搭建HTTP服务端和客户端. 创建Web服务器 server.js /** * node-http 服务端 */ let http = req ...

  6. Nginx 使用(server参数配置)

    文件地址nginx/conf/Nginx.conf 文件地址;nginx/conf/Nginx.conf [java] view plain copy server {# 服务名及配置,一个服务下可以 ...

  7. Python文本文件的输入输出操作学习

    Python具有基本的文本文件读写功能.Python的标准库提供有更丰富的读写功能. 文本文件的读写主要通过open()所构建的文件对象来实现. 创建文件对象 我们打开一个文件,并使用一个对象来表示该 ...

  8. 2017秋软工 —— 本周PSP

    1. PSP 2. PSP饼图 3. 累计进度条 4. 累计折线图

  9. 软件工程-东北师大站-第十一次作业(PSP)

    PSP 饼状图 2.本周进度条 3.本周累计进度图 代码累计折线图 博文字数累计折线图  

  10. 【动态规划】POJ-2229

    一.题目 Description Farmer John commanded his cows to search for different sets of numbers that sum to ...