5248: [2018多省省队联测]一双木棋

Time Limit: 20 Sec  Memory Limit: 512 MB
Submit: 43  Solved: 34
[Submit][Status][Discuss]

Description

菲菲和牛牛在一块n行m列的棋盘上下棋,菲菲执黑棋先手,牛牛执白棋后手。棋局开始时,棋盘上没有任何棋子,
两人轮流在格子上落子,直到填满棋盘时结束。落子的规则是:一个格子可以落子当且仅当这个格子内没有棋子且
这个格子的左侧及上方的所有格子内都有棋子。
棋盘的每个格子上,都写有两个非负整数,从上到下第i行中从左到右第j列的格子上的两个整数记作Aij、Bij。在
游戏结束后,菲菲和牛牛会分别计算自己的得分:菲菲的得分是所有有黑棋的格子上的Aij之和,牛牛的得分是所
有有白棋的格子上的Bij的和。
菲菲和牛牛都希望,自己的得分减去对方的得分得到的结果最大。现在他们想知道,在给定的棋盘上,如果双方都
采用最优策略且知道对方会采用最优策略,那么,最终的结果如何

Input

第一行包含两个正整数n,m,保证n,m≤10。
接下来n行,每行m个非负整数,按从上到下从左到右的顺序描述每个格子上的
第一个非负整数:其中第i行中第j个数表示Aij。
接下来n行,每行m个非负整数,按从上到下从左到右的顺序描述每个格子上的
第二个非负整数:其中第i行中第j个数表示Bij
n, m ≤ 10 , Aij, Bij ≤ 100000

Output

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

Sample Input

2 3
2 7 3
9 1 2
3 7 2
2 3 1

Sample Output

2

HINT

Source

[Submit][Status][Discuss]

这套卷子真的是CCF卷的风格。。专门克制我这种做题慢如蜗牛的人。。

首先这个题一看范围就差不多了,不是搜索就是DP,要拿满分显然得记忆化。因为博弈的最佳决策是根据后继状态选择的,所以返回的是某个状态之后可能拉出的最大/最小分差。由于先手是想让A-B最大,后手反之,交替进行,所以我们搜索时分两种情况讨论一下,最终一定能得到最优决策下的答案。

至于怎么存储当前状态,直接状压每行放了多少个棋子即可,状态直接转移。我起先是按照11进制存储状态的,发现跑了0.99s,后来改成16进制用位运算代替除法取模,就只要0.29s了。

还有一种方法是连通性DP,将从左下到右上的轮廓线压进二进制里转移(0表示向上,1表示向右)。

方法一:

 #include<cstdio>
#include<algorithm>
#define rep(i,l,r) for (int i=l; i<=r; i++)
typedef long long ll;
using namespace std; const int N=,inf=,P=;
ll H[P],G; int H1[P];
int n,m,a[N][N],b[N][N],p[N]; void inc(int &x){ x++; if (x>=P) x-=P; }
void Hash(ll S,int k){ int x=S%P; while (H[x]) inc(x); H[x]=S; H1[x]=k; }
int Find(ll S){ int x=S%P; while (H[x]!=S && H[x]) inc(x); return H1[x]; } int get(ll S,int x){ if (!x) return m; x=n-x; while (x--) S>>=; return S&; }
ll upd(ll S,int x){
if (x==){
int tot=;
rep(i,,n-) p[tot++]=S&,S>>=; S++;
while (tot--) S=(S<<)+p[tot];
return S;
}
int tot=;
rep(i,,n-x) p[tot++]=S&,S>>=; S++;
while (tot--) S=(S<<)+p[tot];
return S;
} int dfs(ll S,int x){
int t=Find(S); if (t) return t;
if (S==G-) return (x ? -b[n][m] : a[n][m]);
if (x==){
int res=-inf;
rep(i,,n) if (get(S,i)<get(S,i-)) res=max(res,a[i][get(S,i)+]+dfs(upd(S,i),x^));
Hash(S,res); return res;
}else{
int res=inf;
rep(i,,n) if (get(S,i)<get(S,i-)) res=min(res,dfs(upd(S,i),x^)-b[i][get(S,i)+]);
Hash(S,res); return res;
}
} int main(){
freopen("chess.in","r",stdin);
freopen("chess.out","w",stdout);
scanf("%d%d",&n,&m);
rep(i,,n) G=G*+m;
rep(i,,n) rep(j,,m) scanf("%d",&a[i][j]);
rep(i,,n) rep(j,,m) scanf("%d",&b[i][j]);
printf("%d\n",dfs(,));
return ;
}

方法二:

 #include<cstdio>
#include<algorithm>
#define rep(i,l,r) for (int i=l; i<=r; i++)
using namespace std; const int N=,inf=;
int n,m,a[N][N],b[N][N],f[<<],p[]={}; int cnt(int x){ int res=; for (; x; x>>=) if (x&) res++; return res; }
int work(int x){
int res=,w=;
for (; x; x>>=) if (x&) res+=w; else w++;
return res;
}
int valA(int v,int s){ int g=cnt(v&(p[s]-)); return a[n-s+g][+g]; }
int valB(int v,int s){ int g=cnt(v&(p[s]-)); return b[n-s+g][+g]; } void solve(int S,int x){
int res;
if (x){
res=inf;
for (int i=; i<n+m-; i++)
if (!(p[i]&S) && (p[i+]&S))
res=min(res,f[S^p[i]^p[i+]]-valB(S,i));
}else{
res=-inf;
for (int i=; i<n+m-; i++)
if (!(p[i]&S) && (p[i+]&S))
res=max(res,f[S^p[i]^p[i+]]+valA(S,i));
}
f[S]=res;
} int main(){
freopen("chess.in","r",stdin);
freopen("chess.out","w",stdout);
scanf("%d%d",&n,&m);
rep(i,,n) rep(j,,m) scanf("%d",&a[i][j]);
rep(i,,n) rep(j,,m) scanf("%d",&b[i][j]);
p[]=; rep(i,,n+m) p[i]=p[i-]<<;
f[p[m]-]=;
rep(i,p[m],p[n+m]-p[n])
if (cnt(i)==m) solve(i,(n*m-work(i))&);
printf("%d\n",f[p[n+m]-p[n]]);
return ;
}

[BZOJ5248][九省联考2018]一双木棋(连通性DP,对抗搜索)的更多相关文章

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

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

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

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

  3. BZOJ5248:[九省联考2018]一双木棋——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=5248 https://www.luogu.org/problemnew/show/P4363#su ...

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. 【ALB学习笔记】基于多线程方式的串行通信接口数据接收案例

    基于多线程方式的串行通信接口数据接收案例 广东职业技术技术学院  欧浩源 1.案例背景 在本博客的<[CC2530入门教程-06]CC2530的ADC工作原理与应用>中实现了电压数据采集的 ...

  2. poj 2253 Frogger (dijkstra最短路)

    题目链接:http://poj.org/problem?id=2253 Frogger Time Limit: 1000MS   Memory Limit: 65536K Total Submissi ...

  3. Eudyptula Challenge

    http://www.eudyptula-challenge.org/ The Eudyptula Challenge What is it? The Eudyptula Challenge is a ...

  4. jQuery Validate插件 验证实例

    官网地址:http://bassistance.de/jquery-plugins/jquery-plugin-validation Validate手册: http://www.cnblogs.co ...

  5. vue做购物车

    写一点废话,昨天敲代码找bug,找了好久都没找到,后来一哥们找到他说,找代码的bug就像男女朋友吵架,女问男你错了没,男说错啦,女再问错哪了,男傻眼了不知道错哪.在找代码的过程中一直知道我错啦就是找不 ...

  6. MyBatis3-与Spring 4集成

    继续使用前一篇的例子http://www.cnblogs.com/EasonJim/p/7052368.html,实际项目中,通常会用Spring来管理DataSource等.充分利用Spring基于 ...

  7. 《逐梦旅程 WINDOWS游戏编程之从零开始》笔记4——Direct3D编程基础

    第11章 Direct3D编程基础 2D游戏是贴图的艺术,3D游戏是渲染的艺术.这句话在我学过了之前的GDI编程之后,前一句算是有所体会,现在是来理解后一句的时候了. 安装DirectX SDK配置啥 ...

  8. redis之(三)redis的数据类型

    [一]字符串类型(基本数据类型) --->字符串类型是redis的最基本的数据类型 --->能存储任何形式的字符串,(用户邮箱,json化的对象,一张图片) --->一个字符串类型的 ...

  9. 寻找与网页内容相关的图片(二)reddit的做法

    正如前文所述,内容聚合网站,比如新浪微博.推特.facebook等网站对于网页的缩略图是刚需.为了让分享的内容引人入胜,网页的图片缩略图是必不可少的.年轻人的聚集地.社交新闻网站reddit也是一个这 ...

  10. C#获取网页信息核心方法(入门一)

    目录:信息采集入门系列目录 下面记录的是我自己整理的C#请求页面核心类,主要有如下几个方法 1.HttpWebRequest Get请求获得页面html 2.HttpWebRequest Post请求 ...