loj2471[九省联考2018]一双木棋
题意:在一个n*m的棋盘上,A和B轮流放置棋子。一个位置能够放置棋子当且仅当它上面没有棋子并且它的上面和左边一格都已经放了棋子(不难发现是一个上三角阶梯状)。每个格子有两个权值,当A在上面放置棋子时A获得a[i][j]的得分,B同理。
A和B用最优策略,A想要A-B最大,B想要B-A最大(即使A-B最小)。问最后A-B为多少?
标程:
#include<bits/stdc++.h>
using namespace std;
int read()
{
int x=,f=;char ch=getchar();
while (ch<''||ch>'') {if (ch=='-') f=-;ch=getchar();}
while (ch>=''&&ch<='') x=(x<<)+(x<<)+ch-'',ch=getchar();
return x*f;
}
const int inf=0x3f3f3f3f;
map<int,int> mp;
int n,m,a[][],b[][],vis[],w[][];
int dfs(int op,int hsh)
{
if (mp[hsh]) return mp[hsh];
if (vis[n]==m) return ;
int ans=(op==)?inf:-inf;
for (int i=;i<=n;i++)
if (vis[i]!=vis[i-]&&vis[i]!=m)
{
vis[i]++;
if (op==) ans=min(ans,dfs(op^,hsh^w[i][vis[i]])-b[i][vis[i]]);
else ans=max(ans,dfs(op^,hsh^w[i][vis[i]])+a[i][vis[i]]);
vis[i]--;
}
return mp[hsh]=ans;
}
int main()
{
srand(time(NULL));
n=read();m=read();
for (int i=;i<=n;i++)
for (int j=;j<=m;j++) a[i][j]=read();
for (int i=;i<=n;i++)
for (int j=;j<=m;j++) b[i][j]=read(),w[i][j]=rand();
vis[]=;
printf("%d\n",a[][]+dfs(,));
return ;
}
题解:决策性搜索+记忆化
每一行保存扩展到哪里,这个hash成状态S。dfs(S)表示在S补的状态下A-B的值。
A先手,取max(dfs(S')+a[i][j])。B先手,取min(dfs(S')-b[i][j])。
不想写hash写个熟练的随机权值异或一下:)。搜索用map记忆化要习惯。
P.S.自己写的时候dfs表示当前局面的先手-后手的得分,绕来绕去较难写。写程序要写得聪明点。
对于某个状态S,先后手是谁可以通过取格子数唯一确定,不需要压进map。
loj2471[九省联考2018]一双木棋的更多相关文章
- 洛谷 P4363 [九省联考2018]一双木棋chess 解题报告
P4363 [九省联考2018]一双木棋chess 题目描述 菲菲和牛牛在一块\(n\)行\(m\)列的棋盘上下棋,菲菲执黑棋先手,牛牛执白棋后手. 棋局开始时,棋盘上没有任何棋子,两人轮流在格子上落 ...
- [BZOJ5248][九省联考2018]一双木棋(连通性DP,对抗搜索)
5248: [2018多省省队联测]一双木棋 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 43 Solved: 34[Submit][Status ...
- Luogu4363 [九省联考2018]一双木棋chess 【状压DP】【进制转换】
题目分析: 首先跑个暴力,求一下有多少种状态,发现只有18xxxx种,然后每个状态有10的转移,所以复杂度大约是200w,然后利用进制转换的技巧求一下每个状态的十进制码就行了. 代码: #includ ...
- luogu P4363 [九省联考2018]一双木棋chess
传送门 对抗搜索都不会,我真是菜死了qwq 首先根据题目条件,可以发现从上到下每一行的棋子数是单调不增的,然后n m都比较小,如果把状态搜出来,可以发现合法状态并不多,所以可以用一个11进制数表示状态 ...
- [九省联考2018]一双木棋chess
题解: 水题吧 首先很显然的是状压或者搜索 考虑一下能不能状压吧 这个东西一定是长成三角形的样子的 所以是可以状压的 相邻两位之间有几个0代表他们差几 这样最多会有2n 然后就可以转移了 由于之前对博 ...
- 【题解】Luogu P4363 [九省联考2018]一双木棋chess
原题传送门 这道题珂以轮廓线dp解决 经过推导,我们珂以发现下一行的棋子比上一行的棋子少(或等于),而且每一行中的棋子都是从左向右依次排列(从头开始,中间没有空隙) 所以每下完一步棋,棋盘的一部分是有 ...
- P4363 [九省联考2018]一双木棋chess
思路 容易发现只能在轮廓线的拐点处落子,所以棋盘的状态可以用一个n+m长度的二进制数表示 转移就是10变成01 代码 #include <cstdio> #include <algo ...
- [九省联考2018] 一双木棋 chess
Description 菲菲和牛牛在一块n 行m 列的棋盘上下棋,菲菲执黑棋先手,牛牛执白棋后手. 棋局开始时,棋盘上没有任何棋子,两人轮流在格子上落子,直到填满棋盘时结束. 落子的规则是:一个格子可 ...
- BZOJ.5248.[九省联考2018]一双木棋chess(对抗搜索 记忆化)
BZOJ 洛谷P4363 [Update] 19.2.9 重做了遍,感觉之前写的有点扯= = 首先棋子的放置情况是阶梯状的. 其次,无论已经放棋子的格子上哪些是黑棋子哪些是白棋子,之前得分如何,两人在 ...
随机推荐
- 【C/C++】知识点系统复习 (第一周)
2018/12/18 周二 1. C++内存布局分为几个区域,每个区域有什么特点? 主要可以分为 5 个区域, (1) 栈区:由编译器自动分配释放,存放函数的参数值,局部变量的值等.其操作方式类似于数 ...
- Python3.5-20190508-廖老师-自我笔记-迭代器
可以实现for ...in 的都可以称为,可迭代对象,Iterable 可以使用isinstance(是什么实例嘛)来判断是不是可迭代对象 可以被next()函数调用并不断返回下一个值的对象称为迭代器 ...
- 微信小程序学习一 微信小程序的四个基本文件
微信小程序有四种类型的文件 js 类型文件 小程序的逻辑代码文件 小程序对js es6的处理比较友好,基本上我们的es6语法都需要使用babel插件去转化成es5(具体是什么原因,自己可以去了解一下) ...
- Windows7有“系统保留”分区时,安装系统要注意的两点
1.手动格式化“系统保留”分区 2.格式化完成之后,安装系统到第二个分区,不能安装到“系统保留”分区 具体看图: 本文章转载于辰羿的博客,如有侵权请联系本论坛维护者删除.
- 目标检测中roi的有关操作
1.roi pooling 将从rpn中得到的不同Proposal大小变为fixed_length output, 也就是将roi区域的卷积特征拆分成为H*W个网格,对每个网格进行maxpooling ...
- javascript 操作cookies详解
javascript 操作cookies详解 这段操作cookies的方法我使用很久了,但是一直一来没遇到什么问题,今天在做一个在第一个页面保存了cookies,第二个页面获取或者第三个页面获取的功能 ...
- 微信小程序 摇一摇
本次案例是有一点像微信的那个摇一摇但是没有那么好看,一些APP也有看到摇一摇功能. 小程序虽然没有提供摇一摇API接口,但是也一个加速器API ,加上搜索一些大神的资料,我这里就做了一个dome, ...
- 【dart学习】-- Dart之JSON
概述 现在很难想象移动应用程序不需要与后台交互或者存储结构化数据.现在开发,数据传输方式基本都是用JSON,在Flutter中是没有GSON/Jackson/Moshi这些库,因为这些库需要运行时反射 ...
- Python(二)
函数Python的函数支持递归.默认参数值.可变参数,但不支持函数重载.为了增强代码的可读性,可以在函数后书写“文档字符串”(Documentation Strings,或者简称docstrings) ...
- H5 调用 手机设备的功能
1.调用 邮件 : 参考 https://blog.csdn.net/github_38516987/article/details/77637546 (亲测有效) <a href=" ...