题目传送门


分析

菲菲想让答案尽量大,牛牛想让答案尽量小。

很天真的一种想法就是设 \(dp[i][j]\) 表示现在选择 \((i,j)\) 的答案。

但是这样有一个弊端就是并不知道其它位置怎么选择。

准确来说,已经被选择的位置和未被选择的位置存在一条分割线,或者直接叫轮廓线。

设横着的轮廓表示0,竖着的轮廓表示1,那么一开始的轮廓线从左下往右上看就是 \(n\) 个 \(1\) 和 \(m\) 个 \(0\)。

然后每次选择的位置就是形如 \(\dots10\dots\) 的 \(0\) 所在的位置,每次选择一个合适的位置将这个数算进贡献中。

可以发现每种轮廓线只能被其中一个人选择,转移大概就是如果是菲菲操作,那么加 \(a_{x,y}\) 取最大值,否则牛牛减 \(b_{x,y}\) 取最小值。

那么这样可用的状态实则为 \(\binom{n+m}{n}\) 个,记忆化一下就可以了。


代码

#include <iostream>
#include <cstring>
using namespace std;
const int _inf=0xcfcfcfcf;
int dp[1<<20],n,m,a[11][11],b[11][11];
void Min(int &x,int y){x=x<y?x:y;}
void Max(int &x,int y){x=x>y?x:y;}
int dfs(int S,int opt){
if (dp[S]!=_inf) return dp[S];
if (opt) dp[S]=-dp[S];
int x=1,y=m;
for (int i=0;i<(n+m-1);++i){
if (((S>>i)&3)==2){
int _S=S^(3<<i);
if (!opt) Max(dp[S],dfs(_S,1)+a[x][y]);
else Min(dp[S],dfs(_S,0)-b[x][y]);
}
if ((S>>i)&1) ++x;
else --y;
}
return dp[S];
}
int main(){
ios::sync_with_stdio(0);
cin>>n>>m;
for (int i=1;i<=n;++i)
for (int j=1;j<=m;++j) cin>>a[i][j];
for (int i=1;i<=n;++i)
for (int j=1;j<=m;++j) cin>>b[i][j];
memset(dp,0xcf,sizeof(dp));
dp[(1<<n)-1]=0;
cout<<dfs(((1<<n)-1)<<m,0);
return 0;
}

#轮廓线dp,博弈论#洛谷 4363 [九省联考 2018] 一双木棋 chess的更多相关文章

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

    P4363 [九省联考2018]一双木棋chess 题目描述 菲菲和牛牛在一块\(n\)行\(m\)列的棋盘上下棋,菲菲执黑棋先手,牛牛执白棋后手. 棋局开始时,棋盘上没有任何棋子,两人轮流在格子上落 ...

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

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

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

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

  4. Luogu 4363 [九省联考2018]一双木棋chess

    发现数据范围很小,想到状压dp,然后就愣住不会了. 表示太菜了并没有接触过轮廓线dp这种操作. 首先发现合法的操作过程中一定是这样子的: 按照行来看发现每一行单调不递增. 我们用$1$来表示竖着的轮廓 ...

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

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

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

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

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

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

  8. Luogu4363 [九省联考2018]一双木棋chess 【状压DP】【进制转换】

    题目分析: 首先跑个暴力,求一下有多少种状态,发现只有18xxxx种,然后每个状态有10的转移,所以复杂度大约是200w,然后利用进制转换的技巧求一下每个状态的十进制码就行了. 代码: #includ ...

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

    题解: 水题吧 首先很显然的是状压或者搜索 考虑一下能不能状压吧 这个东西一定是长成三角形的样子的 所以是可以状压的 相邻两位之间有几个0代表他们差几 这样最多会有2n 然后就可以转移了 由于之前对博 ...

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

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

随机推荐

  1. Go语言并发编程(3):sync包介绍和使用(上)-Mutex,RWMutex,WaitGroup,sync.Map

    一.sync 包简介 在并发编程中,为了解决竞争条件问题,Go 语言提供了 sync 标准包,它提供了基本的同步原语,例如互斥锁.读写锁等. sync 包使用建议: 除了 Once 和 WaitGro ...

  2. C++ STL学习

    C++ STL学习 目录 C++ STL学习 容器库概览 对可以保存在容器中的元素的限制 容器支持的操作 所有容器都支持的操作或容器成员 迭代器 迭代器的公共操作 迭代器的类型 迭代器的const属性 ...

  3. ThreadLocal的应用场景和注意事项有哪些?

    https://cloud.tencent.com/developer/article/1618405

  4. 项目实战:医疗流式细胞术数据文件(.fcs)导出excel表工具

    需求    解析医疗实验室数据文件*.fcs.   Demo导出数据   医疗流式细胞术数据文件标准(.fcs)   流式细胞术数据文件标准于1984年发布,以促进流式细胞术数据分析软件与在不同类型的 ...

  5. 使用OpenTelemetry进行监控

    工具介绍 注意:该部分介绍摘抄自:https://www.aiwanyun.cn/archives/174 Prometheus.Grafana.Node Exporter 和Alertmanager ...

  6. SpringCloud Hystrix断路器的基本使用

    官网资料: https://github.com/Netflix/Hystrix/wiki/How-To-Use 1. 服务雪崩 分布式系统面临的问题 复杂分布式体系结构中的应用程序有数十个依赖关系, ...

  7. Java 演示线程的死锁问题

    1 package bytezero.deadlock; 2 3 /** 4 * 演示线程的死锁问题: 5 * 6 * 1.死锁的理解:不同的线程分别占用对方需要的同步资源不放弃,都在等待对方放弃 7 ...

  8. Java 类的结构之三 :构造器(或构造方法,constructor)的使用

    1 /* 2 * 类的结构之三 :构造器(或构造方法,constructor)的使用 3 * construct:建设 建造 4 * 5 * 一.构造器的作用: 6 * 创建对象 7 * 初始化对象的 ...

  9. Dungeon Master 题解

    这道题的题意简单来说:就是在3D迷宫里找出口,也就是三维地图,需要用到三维数组 由于本人写代码极易出错,所以在输入三维数组的时候修改了c(column,即列)的值,重复定义了没看到==,后面改成定义成 ...

  10. 安卓开发Android Studio新版本menu菜单不显示的问题

    在新版本的Android Studio   直接配置菜单会显示不出来,新版本新建菜单经节如下: activity_main.xml(布局文件): <?xml version="1.0& ...