【极值问题】【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 int

typedef 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

时间: 2024-07-30 15:22:10

【极值问题】【CF1063B】 Labyrinth的相关文章

$CF1063B\ Labyrinth$ $01$最短路/$01BFS$

\(Des\) 有一个网格图,上面的格子分为空地和障碍,障碍是不可以走的.现在从给定的起点出发开始到处乱走,最多可以往左走\(l\)次,往右走\(r\)次.求可能到达的点数. \(Sol\) 如果只限制了向左或向右走的次数就要简单一些,所以我们先思考这一种情形. 假设只限制了向左走不能超过\(l\)次.这样转化:对于每个点,它向左走花费的代价是\(1\),其他方向的代价是\(0\).求从给定起点出发,走到每一个点的最小花费.对于某一个点,如果这个花费是\(\leq l\)的,那么这个位置就是可达

题解 CF1063B 【Labyrinth】

题解 CF1063B [Labyrinth] 完了我发现我做CF的题大部分思路都和别人不一样qwq 这道题其实很水,不至于到紫题 我们只要bfs一下,向四个方向剪下枝,就A了(好像还跑的蛮快?) 是一道锻炼代码能力的好题 Code: #include <bits/stdc++.h> #define check(x, y) (x >= 0 && x < n && y >= 0 && y < m)//判断是否越界 const

极值问题

题目: 已知m.n为整数,且满足下列两个条件: ① m.n∈1,2,...,K,(1≤K≤10^9) ② (n^ 2-mn-m^2)^2=1 编一程序,对给定K,求一组满足上述两个条件的m.n,并且使m^2+n^2的值最大.例如,若K=1995,则m=987,n=1597,则m.n满足条件,且可使m^2+n^2的值最大. 输入 输入仅一行,K的值. 输出 输出仅一行,m^2+n^2的值. 样例输入 1995 样例输出 3524578 题目字数不多,但是条件2看起来貌似有点复杂,但实际上,它也是个

ACM-百度之星资格赛之Labyrinth——hdu4826

Labyrinth Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 152    Accepted Submission(s): 76 Problem Description 度度熊是一仅仅喜欢探险的熊,一次偶然落进了一个m*n矩阵的迷宫,该迷宫仅仅能从矩阵左上角第一个方格開始走,仅仅有走到右上角的第一个格子才算走出迷宫,每一次仅仅能走

URAL 1033 Labyrinth(DFS)

Administration of the labyrinth has decided to start a new season with new wallpapers. For this purpose they need a program to calculate the surface area of the walls inside the labyrinth. This job is just for you! The labyrinth is represented by a m

vijos - P1543极值问题(斐波那契数列 + 公式推导 + python)

P1543极值问题 Accepted 标签:[显示标签] 背景 小铭的数学之旅2. 描述 已知m.n为整数,且满足下列两个条件: ① m.n∈1,2,-,K ② (n^ 2-mn-m^2)^2=1 编一程序,对给定K,求一组满足上述两个条件的m.n,并且使m^2+n^2的值最大.例如,若K=1995,则m=987,n=1597,则m.n满足条件,且可使m^2+n^2的值最大. 格式 输入格式 输入仅一行,K的值. 输出格式 输出仅一行,m^2+n^2的值. 样例1 样例输入1[复制] 1995

2014年百度之星程序设计大赛 - 资格赛 1004 -- Labyrinth

Labyrinth Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1453    Accepted Submission(s): 500 Problem Description 度度熊是一只喜欢探险的熊,一次偶然落进了一个m*n矩阵的迷宫,该迷宫只能从矩阵左上角第一个方格开始走,只有走到右上角的第一个格子才算走出迷宫,每一次只能走一格,

URAL 1145. Rope in the Labyrinth(两次BFS啊 )

题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1145 1145. Rope in the Labyrinth Time limit: 0.5 second Memory limit: 64 MB A labyrinth with rectangular form and size m × n is divided into square cells with sides' length 1 by lines that are paralle

ZOJ 3762 Pan&#39;s Labyrinth 计算几何

题意:给出一系列的坐标,要求出这些坐标中组成的三角形中最大的高是多少 下列两个假设必然有一个成立 1.点C是所有点中距离点A最远的 2.点C是所有点中距离点B最远的 #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #include<iostream> using namespace std; struct point { double x,y; }p[5