题目:传送门

题目概要:有一个n行m列的矩阵,每一个格子都有一个高度,路径只能从高处向低处扩散,问你如果最后一行可以全部被覆盖,最少要从第一行多少个格子开始,如果不能使最后一行全部被覆盖,求有多少个格子不能;

看完这道题,最直接的想法就是直接定义dx,dy两个数组表示上下左右走,看看第一行每一个格子能对应多少个最后一行的格子。

然后再设置一个vis数组表示最后一行是否已经被到达过,如果最后一行有点还没有被到达过,就输出0和vis=0的格子数量

但是当我们想要实现的时候,发现如果第一行的某个点对应的最后一行的点是断断续续的,那就很舒(e)服(xin)了

buuuut~

似乎可以证明,对于每一个第一行的点,他所对应的最后一行的点总是连续的

反证法:假设可以不连续

我们来看图

如图,这是一条从上到下的连续的路径,用红色标记

现在我们假设从第一行开始有这么一条路径不连续,如图,用蓝色表示

我们会发现,这样的话一定会有重合的路径,用紫色表示

既然这样,从第一行蓝色点出发也一定能够到达最下层的红色点

那么最下面一行的区间一定是连续的,证毕(这里不连续是因为有无解的情况)

有了这个结论,只要不是无解的情况,把最后一行的连续区间拿出来,就变成了一个线段覆盖问题

代码:

 #include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<string>
#include<queue>
#include<stack>
#include<time.h>
using namespace std;
typedef long long ll;
ll read(){
ll ans=;
char last=' ',ch=getchar();
while(ch<'' || ch>'')last=ch,ch=getchar();
while(ch>='' && ch<='')ans=ans*+ch-'',ch=getchar();
if(last=='-')ans=-ans;
return ans;
} const int maxn=; int n,m,atlas[maxn][maxn];
int num[maxn][maxn];
bool vis[maxn][maxn];
int dx[]={,-,,},dy[]={,,,-};
int l[maxn][maxn],r[maxn][maxn]; //记忆化搜索
void dfs(int x,int y)
{
vis[x][y]=true;//先标记这个点到达过
for(int i=;i<;i++)//上下左右搜索
{
int nx=x+dx[i],ny=y+dy[i];
if(nx<||nx>n||ny<||ny>m) continue;//判断边界
if(atlas[nx][ny]>=atlas[x][y]) continue;//判断高度
if(!vis[nx][ny])dfs(nx,ny);
l[x][y]=min(l[x][y],l[nx][ny]);
r[x][y]=max(r[x][y],r[nx][ny]);//更新区间左右端点
}
} int main()
{
n=read(),m=read();
memset(vis,false,sizeof(vis));
memset(l,0x3f,sizeof(l));//初始化
for(int i=;i<=m;i++)
{
l[n][i]=r[n][i]=i;//区间初始化
}
for(int i=;i<=n;i++)
{
for(int j=;j<=m;j++)
{
atlas[i][j]=read();
}
} for(int i=;i<=m;i++)
{
if(!vis[][i]) dfs(,i);//如果还没有被到达过,就搜索
} int counti=;
for(int i=;i<=m;i++)
{
if(!vis[n][i]) counti++;
}//看最后一行有没有不能到达的
if(counti!=)
{
cout<<<<endl<<counti;
return ;
} int left=;//记录当前最左边的点
while (left<=m)//跑一遍区间覆盖
{
int maxr=;
for (int i=;i<=m;i++)
if (l[][i]<=left)//如果这个点在区间左端点的右边
maxr=max(maxr,r[][i]);//寻找右端点最大的
counti++;
left=maxr+;//继续更新
}
cout<<<<endl<<counti;
return ;
}

NOIP 2010 P1514 引水入城的更多相关文章

  1. 洛谷P1514 引水入城

    洛谷P1514 引水入城 原题链接 一道好题...细节真多 第一次提交90分,然后就GG了,不知从何改起 其实比较简单吧... 首先,一个点的水流向最后一排,一定可以形成一个区间. 不行的话肯定GG ...

  2. 洛谷 P1514 引水入城 解题报告

    P1514 引水入城 题目描述 在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个 NN 行 \times M×M 列的矩形,如上图所示,其中每个格 ...

  3. [luogu]P1514 引水入城[搜索][记忆化][DP]

    [luogu]P1514 引水入城 引水入城 题目描述在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个N 行M 列的矩形 ,如下图所示,其中每个格 ...

  4. CODEVS 1066/洛谷 P1514引水入城

    1066 引水入城 2010年NOIP全国联赛提高组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond   题目描述 Description 在一个遥远的国 ...

  5. 洛谷P1514 引水入城 [搜索,区间DP]

    题目传送门 引水入城 题目描述 在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个 N 行×M 列的矩形,如上图所示,其中每个格子都代表一座城市,每 ...

  6. 【luogu P1514 引水入城】 题解

    题目链接:https://www.luogu.org/problemnew/show/P1514 // luogu-judger-enable-o2 #include <iostream> ...

  7. 洛谷P1514 引水入城——dfs

    题目:https://www.luogu.org/problemnew/show/P1514 搜索+DP: 自己想出来的方法第一次80分好高兴! 再改了改就A了,狂喜乱舞: 也就是 dfs,仔细一想第 ...

  8. P1514 引水入城

    概述 首先,这是一道好题,这道题既考查了图论的dfs知识,又考察了区间贪心问题中很典型的区间覆盖问题,着实是一道好题. 大概思路说明 我们观察到,只有第一行可以放水库,而第一行在哪里放水库的结果就是直 ...

  9. [NOIP2010] 提高组 洛谷P1514 引水入城

    题目描述 在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个N 行M 列的矩形,如上图所示,其中每个格子都代表一座城市,每座城市都有一个海拔高度. ...

随机推荐

  1. VC调试方法大全

    VC调试方法大全 一.调试基础 调试快捷键 F5:  开始调试 Shift+F5: 停止调试 F10:   调试到下一句,这里是单步跟踪 F11:   调试到下一句,跟进函数内部 Shift+F11: ...

  2. python基础循环语句练习

    1.使用while循环输入 1 2 3 4 5 6     8 9 10 n = 1 while n < 11: if n == 7: pass else: print(n) n = n + 1 ...

  3. 简历内容-resume

    1.TCP.UDP通信  服务器客户端  网络层 2.http协议 通信  网络编程  应用层  根据公司给出的应用层协议开发指定程序: 3.json  cjson Cjson解析器 4.freeRT ...

  4. 阻塞队列 BlockingQueue 常用方法详解

    1.offer()和add()的区别 add()和offer()都是向队列中添加一个元素.但是如果想在一个满的队列中加入一个新元素,调用 add() 方法就会抛出一个 unchecked 异常,而调用 ...

  5. jQuery难学是因为什么?

    我们看别人写的js代码,发现很多不明白,其实只是你对语法不清楚.对函数方法了解的不全面. /****************************************************** ...

  6. Python的魔法方法??

    就是可以给你的类增加魔力的特殊方法,如果你的对象实现 (重载)了这些方法中的某一个,那么这个方法就会在特殊的情况下被 Python 所调用,你可以定义自己想要的行为,而这一切都是自动发生的. __in ...

  7. Python 内置函数raw_input()和input()用法和区别

    我们知道python接受输入的raw_input()和input() ,在python3 输入raw_input() 去掉乐,只要用input() 输入,input 可以接收一个Python表达式作为 ...

  8. HTML创建链接框

    使用CSS样式创建一个漂亮的链接框吧 <!DOCTYPE html> <html> <head> <style> a:link,a:visited { ...

  9. centos误删除文件如何恢复

    当意识到误删除文件后,切忌千万不要再频繁写入了,否则你的数据恢复的数量将会很少. 而我们要做的是,第一时间把服务器上的服务全部停掉,直接killall 进程名 或者 kill -9 pid . 然后把 ...

  10. nginx windows 代理 80端口 500

    今天准备配置一个nginx 用来代理80端口分别访问.net core 和spring boot 服务器 配置使用的最基本的代理配置 #user nobody; worker_processes 1; ...