【极值问题】【CF1063B】 Labyrinth
传送门
Description
给你一个\(n~\times~m\)的矩阵,一开始你在第\(r\)行第\(c\)列。你的上下移动不受限制,向左最多移动\(x\)次,向右最多移动\(y\)次。求你最多能到多少个点。包括起始点。
Input
第一行是\(n\)和\(m\),代表矩阵规模。
第二行是\(r\)和\(c\),代表你的位置
第三行是\(x\)和\(y\),代表移动限制
下面\(n\)行每行\(m\)个字符,有且仅有'.'和''两种。如果第\(i\)行第\(j\)列是''代表你不能经过这个点。
Output
输出一行一个数代表能到的最多点数
Sample Input
4 5
3 2
1 2
.....
.***.
...**
*....
Sample Output
10
Hint
\(For~All:\)
\(0~\leq~n,m,r,c~\leq~2000\),\(0~\leq~x,y~\leq~10^9\)
Solution
朴素的\(bfs\)显然是对的,可以状态太多存不下。
考虑如果从\((sx,sy)\)点到一个点\((x,y)\)时,假设共向右走了\(r\)步,向左走了\(l\)步,显然\(r-l\)是一个定值。具体的,\(r-l~=~y-sy\)。于是,对于任意一个目标\((x,y)\),发现\(l\)事实上与\(r\)线性正相关。对于一个点,显然到该点的\(r\)越小越好,同时由于\(l\)和\(r\)线性正相关,所以最小化\(r\)的同时,\(l\)已经被最小化了。于是可以直接建图跑最短路,所有向右的边权为1,其他边权为0。跑完后扫描整个地图就可以判断合法性了。
这里的一个新姿势是\(0/1bfs\)。当边权只有\(0/1\)时,可以使用双端队列进行bfs,具体的,当当前边的权值时\(0\)时,将终点压入队首,否则压入队尾。考虑这么做的正确性:易证任意一时刻队列中的点dist差值不超过1。于是正确性显然。\(0/1bfs\)的复杂度为\(O(V+E)\)。相比dij少了一个log。
Code
#include<queue>
#include<cstdio>
#include<cstring>
#define rg register
#define ci const int
#define cl const long long inttypedef long long int ll;namespace IO{char buf[110];
}template <typename T>
inline void qr(T &x) {rg char ch=getchar(),lst=' ';while((ch > '9') || (ch < '0')) lst=ch,ch=getchar();while((ch >= '0') && (ch <= '9')) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();if(lst == '-') x=-x;
}template <typename T>
inline void qw(T x,const char aft,const bool pt) {if(x < 0) {putchar('-');x=-x;}rg int top=0;do {IO::buf[++top]=x%10+'0';} while(x/=10);while(top) putchar(IO::buf[top--]);if(pt) putchar(aft);
}template <typename T>
inline T mmax(const T a,const T b) {return a > b ? a : b;}
template <typename T>
inline T mmin(const T a,const T b) {return a < b ? a : b;}
template <typename T>
inline T mabs(const T a) {return a < 0 ? -a : a;}template <typename T>
inline void mswap(T &a,T &b) {T _temp=a;a=b;b=_temp;
}const int maxn = 2010;const int fx[]={0,-1,0,1};
const int fy[]={1,0,-1,0};
const int fv[]={1,0,0,0};int n,m,sx,sy,x,y;
int MU[maxn][maxn];
char mp[maxn][maxn];std::deque<int>Qx,Qy;int main() {qr(n);qr(m);qr(sx);qr(sy);qr(x);qr(y);for(rg int i=1;i<=n;++i) scanf("%s",mp[i]+1);memset(MU,0x3f,sizeof MU);MU[sx][sy]=0; Qx.push_front(sx);Qy.push_front(sy);while(!Qx.empty()) {int hx=Qx.front(),hy=Qy.front();Qx.pop_front();Qy.pop_front();for(rg int i=0;i<4;++i) {int dx=hx+fx[i],dy=hy+fy[i];if((dx > n) || (dy > m) || (!dx) || (!dy) || (mp[dx][dy] == '*') || (MU[dx][dy] <= MU[hx][hy]+fv[i])) continue;MU[dx][dy]=MU[hx][hy]+fv[i];if(i) {Qx.push_front(dx);Qy.push_front(dy);}else {Qx.push_back(dx);Qy.push_back(dy);}}}rg int _ans=0;for(rg int i=1;i<=n;++i) {for(rg int j=1;j<=m;++j) if(mp[i][j] != '*') {if((MU[i][j] <= y) && ((MU[i][j]-j+sy) <= x)) ++_ans;}}qw(_ans,'\n',true);return 0;
}
Summary
当题设需要最小化多个变量时,不妨考虑变量间的相关关系,从此转化成单变量的极值问题。
当边权只有\(0\)和\(1\)的时候,可以考虑使用\(0/1bfs\),省去dij的log。
转载于:https://www.cnblogs.com/yifusuyi/p/9800308.html
【极值问题】【CF1063B】 Labyrinth相关推荐
- CF1063B Labyrinth
CF1063B Labyrinth 题意: 你正在玩一款电脑游戏.在其中一关,你位于一个 n 行 m 列的迷宫.每个格子要么是可以通过的空地,要么是障碍.迷宫的起点位于第 r 行第 c 列.你每一步可 ...
- 【CF1063B】Labyrinth [最短路? 01BFS]
CF1063B Labyrinth 01BFS 和普通的01BFS不一样的是这题可以重复走 从(sx,sy)到(x,y)假设向左走了l步向右走了r步 则有sx+r-l=x 即l-r=sx-x为定值 所 ...
- 百度之星2014资格赛 1004 - Labyrinth
先上题目: Labyrinth Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- 2014年百度之星程序设计大赛 - 资格赛 1004 Labyrinth(Dp)
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/sr19930829/article/details/26003869 Labyrinth Time ...
- MATLAB 无约束一维极值问题
无约束一维极值问题 极值问题表达式:min f(x) x,x[ x1 x2]; 一维极值的搜索方式包括线性搜索和非线性搜索,线性搜索包含黄金分割法.斐波那契法和牛顿法,非线性方法包含抛物线法 ...
- UA SIE545 优化理论基础3 Fritz-John与Kuhn-Tucker理论总结 带等式约束与不等式约束的极值问题
UA SIE545 优化理论基础3 Fritz-John与Kuhn-Tucker理论总结 带等式约束与不等式约束的极值问题 对于函数f:X→Yf:X \to Yf:X→Y,我们希望XXX是一个凸的度量 ...
- 2019-10-14 无约束条件的泛函极值问题的举例说明
概念说明 泛函:存在函数x(t)x(t)x(t),同时另一函数JJJ依赖于函数x(t)x(t)x(t),表示为J(x)J(x)J(x),就称J(x)J(x)J(x)为x(t)x(t)x(t)的泛函. ...
- 推理计算过程_初中物理电学计算题第六讲:极值问题推理和限制条件
初中物理电学计算题第六讲:极值问题推理和限制条件 前面已经讲过:初中物理电学计算题第三讲:串联电路电流电阻极值推理实例,本讲是这一问题的进一步深入讨论. 题型分析 极值问题是电学计算题中一类较难的题目 ...
- B - Labyrinth Gym - 102798B
B - Labyrinth Gym - 102798B 题意: n * m的地图,有k个障碍物,给你起点到终点,从起点到终点的最短距离 1<=n,m<=200000 nm<=2000 ...
最新文章
- 解决报错:tensorflow.python.framework.errors_impl.UnknownError: Failed to get convolution algorithm.
- mac Hbuilder 无法打开的解决方案
- 三十一、Java多线程编程(下篇)
- golang mysql demo
- HappyLeetcode50:Rotate Array
- h5通过php微信支付宝支付,用H5调用支付微信公众号支付的解析
- react 手指移开_代码简介:React的五个死亡手指
- Linux下文件内容查阅命令
- CyclicBarrier(栅栏)实现高并发测试
- WCF生成的json与Extjs交互的日期型问题
- JS实现图片无缝滚动特效;附addEventListener()方法、offsetLeft和offsetWidth属性。
- 例3.3 哈夫曼树 - 九度教程第30题(哈夫曼树)
- GridView自带分页 1/总页数 首页 下一页 上一页 尾页 X 页 go 实现方法
- 数学物理方法·基础④复平面/辐角/复数表示形式
- 前端实现打电话、发短信邮件
- android兼容oppo手机刘海屏解决方案
- Python案例篇1-pycharm ModuleNotFoundError: No module named ‘xlsxwriter‘
- 阿里云部署Docker(5)----管理和发布您的镜像
- kali-Firefox安装flash插件
- AD20如何设置为中文版