LOJ #2733 [JOI2016春季合宿]Sandwiches (DP)
题目链接
题解
神仙题……
首先可以观察到一个结论: 目标块的两块小三明治一定分别是最后和倒数第二个被吃的。
由此我们可以考虑这两块谁先被吃。这样的好处就是,起初我们一个块被吃的依赖条件是某两个块中有一个被吃就行,现在两个块中的某一个已经钦定了比它更晚,另一个就一定要比它早,这样依赖关系就形成了一张图。
那么有一个\(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)的更多相关文章
- LOJ #2731 [JOI2016春季合宿]Solitaire (DP、组合计数)
题目链接 https://loj.ac/problem/2731 题解 首先一个很自然的思路是,设\(dp[i][j]\)表示选了前\(i\)列,第\(2\)行第\(i\)列的格子是第\(j\)个被填 ...
- LOJ #2734 Luogu P3615 [JOI2016春季合宿]Toilets (结论、贪心)
题目链接 (loj) https://loj.ac/problem/2734 (luogu) https://www.luogu.org/problem/P3615 题解 嗯,考场上肝了\(3h\)然 ...
- BZOJ 4221 [JOI2012春季合宿]Kangaroo (DP)
题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=4221 题解 orz WYC 爆切神仙DP 首先将所有袋鼠按大小排序.考虑从前往后DP, ...
- JOI2017 春季合宿:Railway Trip
自己的AC做法似乎离正解偏了十万八千里而且复杂了不少--不管怎样还是记录下来吧. 题意: 题目链接: JOISC2017 F - AtCoder JOISC2017 F - LOJ \(N\)个车站排 ...
- UOJ356 [JOI2017春季合宿] Port Facility 【启发式合并】【堆】【并查集】
题目分析: 好像跑得很快,似乎我是第一个启发式合并的. 把玩具看成区间.首先很显然如果有两个玩具的进出时间有$l1<l2<r1<r2$的关系,那么这两个玩具一定在不同的栈中间. 现在 ...
- [JOI2017春季合宿]Port Facility[set、二分图]
题意 你有两个栈,有 \(n\) 个货物,每个货物有一个进栈时间和出栈时间(所有时间的并集是1~2n),问有多少种不同的入栈方案. \(n\le 10^6\) 分析 把每个货物的存在看成区间,相交的区 ...
- UOJ #356. 【JOI2017春季合宿】Port Facility
Description 小M有两个本质不同的栈. 无聊的小M找来了n个玩具.之后小M把这n个玩具随机顺序加入某一个栈或把他们弹出. 现在小M告诉你每个玩具的入栈和出栈时间,现在她想考考小S,有多少种方 ...
- UOJ #357. 【JOI2017春季合宿】Sparklers
Description 小S和小M去看花火大会. 一共有 n 个人按顺序排成一排,每个人手上有一个仅能被点燃一次的烟花.最开始时第 K 个人手上的烟花是点燃的. 烟花最多能燃烧 T 时间.每当两个人的 ...
- UOJ356 【JOI2017春季合宿】Port Facility
暴力就是O(n^2)连边,二分图,这样只有22分. 我们考虑优化建边,我们按照左端点排序,对于一个新加进来的线段,我们向左端点距其最近的和他相交的线段连边,别的相交的我们连同色边,当一个点连了两条同色 ...
随机推荐
- 数值优化(Numerical Optimization)学习系列-无梯度优化(Derivative-Free Optimization)
数值优化(Numerical Optimization)学习系列-无梯度优化(Derivative-Free Optimization) 2015年12月27日 18:51:19 下一步 阅读数 43 ...
- DevOps 之 Jenkins 安装、配置、美化、插件及常见错误处理
继续上一篇的话题,既然已经搭建了 GitLab 的代码仓库,那么现在就可以开始进行下一步持续集成环境的搭建了.公司准备利用 Jenkins CI 进行持续集成,本文记录了 Jenkins 的安装.基础 ...
- webSocket协议和Socket.IO
一.Http无法轻松实现实时应用: ● HTTP协议是无状态的,服务器只会响应来自客户端的请求,但是它与客户端之间不具备持续连接. ● 我们可以非常轻松的捕获浏览器上发生的事件(比如用户点击了盒子), ...
- sql server存储过程回滚事务
SET NOCOUNT ON这个很常用 作用:阻止在结果集中返回显示受T-SQL语句或则usp影响的行计数信息. 当SET ONCOUNT ON时候,不返回计数,当SET NOCOUNT OFF时候, ...
- 关于Webpack打包报错Class constructor FileManager cannot be invoked without 'new'
前端代码部署一直是自己打包之后将文件用FileZilla上传到服务器上,现在改用运维基于到k8s docker镜像的发布,前端打包报错如下: 经查资料,报错原因是less升级导致的Bug 尝试升级le ...
- centos8/redhat8 无法上网,通过启动systemctl start NetworkManger搞定
在systemd里面,可以直接使用systemctl进行管理 启动:systemctl start NetworkManger 关闭:systemctl stop NetworkManager 开机启 ...
- 在Mysql中使用索引
MySQL查询的优化是个老生常谈的问题,方法更是多种多样,其中最直接的就是创建索引. 这里通过一个简单的demo来实际用一下索引,看看索引在百万级别查询中速率的提升效果如何 所需数据可以从我前面的一篇 ...
- Pysnooper 一款大受欢迎的Debug模块
Github地址 安装 PIP pip install pysnooper import pysnooper @pysnooper.snoop() def number_to_bits(number) ...
- C++第四次作业--继承与派生
C++ 继承 面向对象程序设计中最重要的一个概念是继承.继承允许我们依据另一个类来定义一个类,这使得创建和维护一个应用程序变得更容易.这样做,也达到了重用代码功能和提高执行效率的效果. 当创建一个类时 ...
- mybatis配置加载源码概述
Mybatis框架里,有两种配置文件,一个是全局配置文件config.xml,另一个是对应每个表的mapper.xml配置文件.Mybatis框架启动时,先加载config.xml, 在加载每个map ...