洛谷 P4363 [九省联考2018]一双木棋chess 解题报告
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 解题报告的更多相关文章
- 洛谷 P4363 [九省联考2018]一双木棋chess 题解
题目链接:https://www.luogu.org/problemnew/show/P4363 分析: 首先博弈,然后考虑棋盘的规则,因为一个子在落下时它的上面和左面都已经没有空位了,所以棋子的右下 ...
- 洛谷P4363 [九省联考2018]一双木棋chess 【状压dp】
题目 菲菲和牛牛在一块n 行m 列的棋盘上下棋,菲菲执黑棋先手,牛牛执白棋后手. 棋局开始时,棋盘上没有任何棋子,两人轮流在格子上落子,直到填满棋盘时结束. 落子的规则是:一个格子可以落子当且仅当这个 ...
- luogu P4363 [九省联考2018]一双木棋chess
传送门 对抗搜索都不会,我真是菜死了qwq 首先根据题目条件,可以发现从上到下每一行的棋子数是单调不增的,然后n m都比较小,如果把状态搜出来,可以发现合法状态并不多,所以可以用一个11进制数表示状态 ...
- 【题解】Luogu P4363 [九省联考2018]一双木棋chess
原题传送门 这道题珂以轮廓线dp解决 经过推导,我们珂以发现下一行的棋子比上一行的棋子少(或等于),而且每一行中的棋子都是从左向右依次排列(从头开始,中间没有空隙) 所以每下完一步棋,棋盘的一部分是有 ...
- P4363 [九省联考2018]一双木棋chess
思路 容易发现只能在轮廓线的拐点处落子,所以棋盘的状态可以用一个n+m长度的二进制数表示 转移就是10变成01 代码 #include <cstdio> #include <algo ...
- P4363 [九省联考2018]一双木棋chess(对抗搜索+记忆化搜索)
传送门 这对抗搜索是个啥玩意儿…… 首先可以发现每一行的棋子数都不小于下一行,且局面可由每一行的棋子数唯一表示,那么用一个m+1进制数来表示当前局面,用longlong存,开map记忆化搜索 然后时间 ...
- BZOJ.5248.[九省联考2018]一双木棋chess(对抗搜索 记忆化)
BZOJ 洛谷P4363 [Update] 19.2.9 重做了遍,感觉之前写的有点扯= = 首先棋子的放置情况是阶梯状的. 其次,无论已经放棋子的格子上哪些是黑棋子哪些是白棋子,之前得分如何,两人在 ...
- [九省联考2018]一双木棋chess——搜索+哈希
题目:bzoj5248 https://www.lydsy.com/JudgeOnline/problem.php?id=5248 洛谷P4363 https://www.luogu.org/prob ...
- P4363 [九省联考2018]一双木棋
题面 这种搜索要把后继状态都跑出来之后取Min/Max 也就是回溯的时候进行操作 记得用hash进行记忆化(用map不开O2会TLE) #include<iostream> #includ ...
随机推荐
- vim文本编辑工具(全)
VIM文本编辑工具 编辑模式 i 在当前字符前插入I 在光标所在的行首插入a 在当前字符后插入A 在光标所在行尾插入o 在当前行的下一行插入新的一行O 在当前行的上一行插入新的一行 s ...
- Netty源码分析第8章(高性能工具类FastThreadLocal和Recycler)---->第3节: recycler的使用和创建
Netty源码分析第八章: 高性能工具类FastThreadLocal和Recycler 第三节: recycler的使用和创建 这一小节开始学习recycler相关的知识, recycler是n ...
- Playfair加密
前面讲的不管是单码加密还是多码加密都属于单图加密,什么是单图加密和多图加密呢,简单来说单图加密就是一个字母加密一个字母,而多图加密就是一个字符组加密一个字符组.比如双图加密就是两个字母加密两个字母,这 ...
- React的setState分析
前端框架层出不穷,不过万变不离其宗,就是从MVC过渡到MVVM.从数据映射到DOM,angular中用的是watcher对象,vue是观察者模式,react就是state了. React通过管理状态实 ...
- OO第二阶段作业总结
第五次作业: 设计策略: 本次作业设计的基本思路是按照指导书所给的推荐方法来完成的,即共用对象为队列盘,线程有电梯.调度器.以及扫描器,扫描器将控制台输入的有效指令加入到队列盘中,调度 ...
- 20145214 《网络对抗技术》 Web基础
20145214 <网络对抗技术> Web基础 1.实验后回答问题 (1)什么是表单 表单在网页中主要负责数据采集,提供了填写数据.选择数据,收集数据并提交给后台的功能 一个表单有三个基本 ...
- Beta后续感想/吐槽
感想 磨人的软工实践终于结束了 艰难的度过了一学期,还是写点什么纪念一下吧. 大一大二的时候就听说软工实践是魔鬼般的锻炼,于是当年不知天高地厚的我是很期待的,终于,我大三了. 后来,我长大了. alp ...
- HDU 4539 郑厂长系列故事——排兵布阵 状压dp
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4539 郑厂长系列故事--排兵布阵 Time Limit: 10000/5000 MS (Java/O ...
- HDU 4126 Genghis Khan the Conqueror 最小生成树+树形dp
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4126 Genghis Khan the Conqueror Time Limit: 10000/50 ...
- Apache优化之多路处理模块理解
前言: 当项目被多人访问时导致访问数度变慢,查了许多资料,了解到Apache的核心模块——MPM(多路处理访问模块).在此对MPM的一些知识点进行整理. MPM_WINNT模块 windows系统使用 ...