题目链接

https://loj.ac/problem/2733

题解

神仙题……

首先可以观察到一个结论: 目标块的两块小三明治一定分别是最后和倒数第二个被吃的。

由此我们可以考虑这两块谁先被吃。这样的好处就是,起初我们一个块被吃的依赖条件是某两个块中有一个被吃就行,现在两个块中的某一个已经钦定了比它更晚,另一个就一定要比它早,这样依赖关系就形成了一张图。

那么有一个\(O(n^4)\)的做法: 对于每一个块枚举先吃哪个小三明治,然后DFS求出要先吃这个三明治需要吃掉哪些三明治。

下面还有一个结论: 设对于一个块\((x,y)\) (第\(x\)行第\(y\)列)我们先吃掉了靠左边界的块,那么对于块\((x,y-1)\) (即它左边的块),我们也需要先吃掉靠左边界的块,右同理。

推论: 设\(L(x,y)\)是要先取走块\((x,y)\)靠左边界的块需要取走的块的集合,则\(L(x-1,y)\subset L(x,y)\).

于是枚举每一行,在这一行中从左到右DFS求\(L\), 从右往左DFS求\(R\), 遍历过的点无需再遍历。

总时间复杂度\(O(n^3)\).

代码

#include<bits/stdc++.h>
#define llong long long
#define mkpr make_pair
using namespace std; const int N = 400;
const int INF = 1e8;
char a[N+3][N+3];
int vis[N+3][N+3];
int dp0[N+3][N+3],dp1[N+3][N+3];
int n,m; int dfs(int x,int y,int dir)
{
if(vis[x][y]==-1) {return INF;}
else if(vis[x][y]==1) {return 0;}
vis[x][y] = -1; int ret = 2;
if(a[x][y]=='N')
{
if(dir==1)
{
if(x>1) {ret += dfs(x-1,y,a[x-1][y]=='N'?1:0);}
if(y<m) {ret += dfs(x,y+1,1);}
}
else
{
if(x<n) {ret += dfs(x+1,y,a[x+1][y]=='N'?0:1);}
if(y>1) {ret += dfs(x,y-1,0);}
}
}
else
{
if(dir==1)
{
if(x<n) {ret += dfs(x+1,y,a[x+1][y]=='N'?0:1);}
if(y<m) {ret += dfs(x,y+1,1);}
}
else
{
if(x>1) {ret += dfs(x-1,y,a[x-1][y]=='N'?1:0);}
if(y>1) {ret += dfs(x,y-1,0);}
}
}
if(ret<INF) {vis[x][y] = 1;}
else ret = INF;
return ret;
} int main()
{
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++) scanf("%s",a[i]+1);
for(int i=1; i<=n; i++)
{
memset(vis,0,sizeof(vis));
for(int j=1; j<=m; j++)
{
dp0[i][j] = dp0[i][j-1]+dfs(i,j,0);
if(dp0[i][j]>INF) {dp0[i][j] = INF;}
}
memset(vis,0,sizeof(vis));
for(int j=m; j>=1; j--)
{
dp1[i][j] = dp1[i][j+1]+dfs(i,j,1);
if(dp1[i][j]>INF) {dp1[i][j] = INF;}
}
for(int j=1; j<=m; j++)
{
int ans = min(dp0[i][j],dp1[i][j]);
printf("%d ",ans<INF?ans:-1);
}
puts("");
}
return 0;
}

LOJ #2733 [JOI2016春季合宿]Sandwiches (DP)的更多相关文章

  1. LOJ #2731 [JOI2016春季合宿]Solitaire (DP、组合计数)

    题目链接 https://loj.ac/problem/2731 题解 首先一个很自然的思路是,设\(dp[i][j]\)表示选了前\(i\)列,第\(2\)行第\(i\)列的格子是第\(j\)个被填 ...

  2. LOJ #2734 Luogu P3615 [JOI2016春季合宿]Toilets (结论、贪心)

    题目链接 (loj) https://loj.ac/problem/2734 (luogu) https://www.luogu.org/problem/P3615 题解 嗯,考场上肝了\(3h\)然 ...

  3. BZOJ 4221 [JOI2012春季合宿]Kangaroo (DP)

    题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=4221 题解 orz WYC 爆切神仙DP 首先将所有袋鼠按大小排序.考虑从前往后DP, ...

  4. JOI2017 春季合宿:Railway Trip

    自己的AC做法似乎离正解偏了十万八千里而且复杂了不少--不管怎样还是记录下来吧. 题意: 题目链接: JOISC2017 F - AtCoder JOISC2017 F - LOJ \(N\)个车站排 ...

  5. UOJ356 [JOI2017春季合宿] Port Facility 【启发式合并】【堆】【并查集】

    题目分析: 好像跑得很快,似乎我是第一个启发式合并的. 把玩具看成区间.首先很显然如果有两个玩具的进出时间有$l1<l2<r1<r2$的关系,那么这两个玩具一定在不同的栈中间. 现在 ...

  6. [JOI2017春季合宿]Port Facility[set、二分图]

    题意 你有两个栈,有 \(n\) 个货物,每个货物有一个进栈时间和出栈时间(所有时间的并集是1~2n),问有多少种不同的入栈方案. \(n\le 10^6\) 分析 把每个货物的存在看成区间,相交的区 ...

  7. UOJ #356. 【JOI2017春季合宿】Port Facility

    Description 小M有两个本质不同的栈. 无聊的小M找来了n个玩具.之后小M把这n个玩具随机顺序加入某一个栈或把他们弹出. 现在小M告诉你每个玩具的入栈和出栈时间,现在她想考考小S,有多少种方 ...

  8. UOJ #357. 【JOI2017春季合宿】Sparklers

    Description 小S和小M去看花火大会. 一共有 n 个人按顺序排成一排,每个人手上有一个仅能被点燃一次的烟花.最开始时第 K 个人手上的烟花是点燃的. 烟花最多能燃烧 T 时间.每当两个人的 ...

  9. UOJ356 【JOI2017春季合宿】Port Facility

    暴力就是O(n^2)连边,二分图,这样只有22分. 我们考虑优化建边,我们按照左端点排序,对于一个新加进来的线段,我们向左端点距其最近的和他相交的线段连边,别的相交的我们连同色边,当一个点连了两条同色 ...

随机推荐

  1. 《深入实践C++模板编程》之二——模板类

    1.类的模板的使用 类,由于没有参数,所以没有模板实参推导机制. #include <stdexcept> template<typename T> class my_stac ...

  2. Linux之curl

    简介 curl 是常用的命令行工具,用来请求 Web 服务器.它的名字就是客户端(client)的 URL 工具的意思. 它的功能非常强大,命令行参数多达几十种.如果熟练的话,完全可以取代 Postm ...

  3. vue进阶:vuex(数据池)

    非父子组件传值 vuex 一.非父子组件传值 基于父子组件通信与传值实现非父子组件传值的示例关键代码: <template> <div> <!-- 学员展示 --> ...

  4. otter+canal

    https://blog.csdn.net/u011142688/article/details/52046928 https://blog.csdn.net/chenzeyuczy/article/ ...

  5. 测试使用Timer定时调用http接口

    转自:https://blog.csdn.net/qq_36004521/article/details/80101881

  6. java调用ffmpeg获取视频文件信息的一些参数

    一.下载ffmpeg http://www.ffmpeg.org/download.html 主要需要bin目录下的ffmpeg可执行文件 二.java代码实现 package com.aw.util ...

  7. Line 算法与deepwalk的对比 和个人理解

    用户的关注关系本身就是一个图结构,要从用户关注关系生成用户的embedding表示,其实就是做graph的emebding表示. deepwalk+word2vec 比较简单,效果也还可以.这种方法再 ...

  8. deep_learning_Function_os.makedirs()

    Python 3.2+ os.makedirs(path, exist_ok=True) python 3.2创建目录新增了可选参数existok,把existok设置True,创建目录如果已经存在则 ...

  9. python常用模块:sys、os、path、setting、random、shutil

    今日内容讲了3个常用模块 一.sys模块二.os模块三.os下path模块四.random模块五.shutil模块 一.sys模块 import sys #环境变量 print(sys.path) # ...

  10. Centos7添加密码安全策略

    设置密码中至少包含一个小写字符,执行命令:# authconfig --enablereqlower --update查看设置:# grep "^lcredit" /etc/sec ...