洛谷 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 ...
随机推荐
- Dubbo问题处理集合
1 . 启动微服务的时候,报错信息如下: 核心:Can not lock the registry cache file /root/.dubbo/dubbo-registry-127.0.0.1.c ...
- 关于MySql数据库主键及索引的区别
一.什么是索引?索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存.如果没有索引,执行查询时MySQL必须从第一个记录开始扫描整个表的所有记录,直至找到符合要求的记录.表里 ...
- Netty源码分析第5章(ByteBuf)---->第7节: page级别的内存分配
Netty源码分析第五章: ByteBuf 第六节: page级别的内存分配 前面小节我们剖析过命中缓存的内存分配逻辑, 前提是如果缓存中有数据, 那么缓存中没有数据, netty是如何开辟一块内存进 ...
- kubernetes高可用设计-master节点和kubectl
部署master 节点 上一遍是CA证书和etcd的部署,这一篇继续搭建k8s,废话不多说.开始部署. kubernetes master 节点包含的组件有: kube-apiserver kube- ...
- python—索引与切片总结
python中索引与切片的熟练掌握对于字符串的操作很有帮助,梳理如下: (1)索引 S = 'hello world' 1)正向索引 正向索引从0开始,向右依次递增. 2)反向索引 反向索引从-1开始 ...
- Extreme Learning Machine 翻译
本文是作者这几天翻译的一篇经典的ELM文章,是第一稿,所以有很多错误以及不足之处. 另外由于此编辑器不支持MathType所以好多公式没有显示出来,原稿是word文档. 联系:250101249@qq ...
- 一个基于NodeJS开发的APP管理CMS系统
花了大概3周独立开发了一个基于NodeJS的CMS系统,用于公司APP的内容管理( **公司APP?广告放在最后 ^_^ ** ,管理员请理解~~~ )晚上看了部电影还不想睡,闲着也是闲着就作下小小总 ...
- Scrum立会报告+燃尽图(十二月九日总第四十次):视频剪辑与用户反馈
此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2484 项目地址:https://git.coding.net/zhang ...
- Scrum Meeting 3 -2014.11.5
这几天小伙伴们都在努力,研究出不少改进方案并加以设计和实施了,分词算法的优化进度可观,而其他的任务在改进的过程中产生了些问题,对于之前代码的设计感到疑惑,我们找到了上届的学长们咨询,他们也给出了不少建 ...
- 记事本APP之Alpha报告
项目名称 记事本APP 项目版本 Alpha版本 负责人 北京航空航天大学计算机学院 Echo软件团队 联系方式 http://www.cnblogs.com/echo-buaa/ 要求发布日期 20 ...