【NOIP2010】引水入城
以前一直以为是什么高端DP,看了题解才发现是水题,老是这样看题解才能写出来到赛场上怎么办嘛QAQ
原题:
在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠。该国的行政
区划十分特殊,刚好构成一个 N 行 M 列的矩形,如上图所示,其中每个格子都代表一座城 市,每座城市都有一个海拔高度。
为了使居民们都尽可能饮用到清澈的湖水,现在要在某些城市建造水利设施。水利设施 有两种,分别为蓄水厂和输水站。蓄水厂的功能是利用水泵将湖泊中的水抽取到所在城市的 蓄水池中。因此,只有与湖泊毗邻的第 1 行的城市可以建造蓄水厂。而输水站的功能则是通 过输水管线利用高度落差,将湖水从高处向低处输送。故一座城市能建造输水站的前提,是 存在比它海拔更高且拥有公共边的相邻城市,已经建有水利设施。
由于第 N 行的城市靠近沙漠,是该国的干旱区,所以要求其中的每座城市都建有水利 设施。那么,这个要求能否满足呢?如果能,请计算最少建造几个蓄水厂;如果不能,求干 旱区中不可能建有水利设施的城市数目。
首先可以先假设第一行的所有格子都建站了,用bfs即可求出是否能把最后一行完全覆盖以及如果不能完全覆盖没有覆盖到的格子有几个
然后在用一个bfs求出如果在第一行第i个格子建站能在最后一行上覆盖区间的左端点和右端点,容易证明如果在第一行某点建站,在最后一行一定是连续覆盖一个区间
然后区间覆盖dp,if(i>=left[j] && i<=right[j]) f[i]=min(f[i],f[left[j]-1]+1)
需要有一个特判,就是只有一行的情况(如果在第一次bfs把第一行每个点入队的同时也标记上的话似乎就不用搞这个特判)
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int read(){int z=,mark=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')mark=-; ch=getchar();}
while(ch>=''&&ch<=''){z=(z<<)+(z<<)+ch-''; ch=getchar();}
return z*mark;
}
int fx[]={,-,,},fy[]={,,,-};
int m,n,a[][];
int visited[][];
int dui[],tou=;
int ans;
int fleft[],fright[];
int f[];
int bfs1(){
memset(visited,,sizeof(visited));
for(int i=;i<=n;i++) dui[++tou]=i-;
for(int k=;k<=tou;k++){
int x=dui[k]/n+,y=dui[k]%n+;
for(int i=;i<;i++)if(!visited[x+fx[i]][y+fy[i]] && a[x][y]>a[x+fx[i]][y+fy[i]]){
visited[x+fx[i]][y+fy[i]]=-;
dui[++tou]=(x+fx[i]-)*n+y+fy[i]-;
}
}
int ge=;
for(int i=;i<=n;i++) if(!visited[m][i]) ge++;
return ge;
}
void bfs2(int _s){
dui[tou=]=_s-;
for(int k=;k<=tou;k++){
int x=dui[k]/n+,y=dui[k]%n+;
for(int i=;i<;i++)if(visited[x+fx[i]][y+fy[i]]!=_s && a[x][y]>a[x+fx[i]][y+fy[i]]){
visited[x+fx[i]][y+fy[i]]=_s;
dui[++tou]=(x+fx[i]-)*n+y+fy[i]-;
}
}
for(int i=;i<=n;i++) if(visited[m][i]==_s){ fleft[_s]=i;
for(int j=i+;j<=n+;j++) if(visited[m][j]!=_s){ fright[_s]=j-;//注意这里如果枚举到n就有可能n也被覆盖了,然后fright就是0
break;
}
break;
}
}
int main(){
//freopen("ddd.in","r",stdin);
freopen("flow.in","r",stdin);
freopen("flow.out","w",stdout);
memset(f,,sizeof(f));
cin>>m>>n;
for(int i=;i<=m;i++)
for(int j=;j<=n;j++)
a[i][j]=read();
for(int i=;i<=m+;i++) a[i][]=,a[i][n+]=;
for(int i=;i<=n+;i++) a[][i]=,a[m+][i]=;
if(ans=bfs1()){ cout<<((m==) ? : )<<endl<<ans<<endl; return ;}//去你大爷的特判,这里有一行的情况
for(int i=;i<=n;i++) bfs2(i);
f[]=;
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
if(i>=fleft[j] && i<=fright[j])
f[i]=min(f[i],f[fleft[j]-]+);
cout<<<<endl<<f[n]<<endl;
return ;
}
【NOIP2010】引水入城的更多相关文章
- 521. [NOIP2010] 引水入城 cogs
521. [NOIP2010] 引水入城 ★★★ 输入文件:flow.in 输出文件:flow.out 简单对比时间限制:1 s 内存限制:128 MB 在一个遥远的国度,一侧是风景秀 ...
- NOIP2010 引水入城
4引水入城 题目描述 在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个N 行M 列的矩形,如上图所示,其中每个格子都代表一座城市,每座城市都有一个 ...
- NOIP2010引水入城[BFS DFS 贪心]
题目描述 在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个N 行M 列的矩形,如上图所示,其中每个格子都代表一座城市,每座城市都有一个海拔高度. ...
- NOIP2010 引水入城 题解
http://www.rqnoj.cn/problem/601 今天发现最小区间覆盖竟然是贪心,不用DP!于是我又找到这题出来撸了一发. 要找到最上面每个城市分别能覆盖最下面哪些城市,如果最下面有城市 ...
- noip2010 引水入城 bfs+贪心
如果能够实现,每个河边的城市对应的控制区域一定是一条线段. 所以直接bfs每个河边的城市,贪心线段的右端点 #include<cstdio> #include<cstring> ...
- Luogu1514 NOIP2010 引水入城 BFS、贪心
传送门 NOIP的题目都难以写精简题意 考虑最上面一排的某一个点对最下面一排的影响是什么样的,不难发现必须要是一段连续区间才能够符合题意. 如果不是一段连续区间,意味着中间某一段没有被覆盖的部分比周围 ...
- luogu1514 [NOIp2010]引水入城 (bfs+记忆化搜索)
我们先bfs一下看看是否能到最底下的所有点 如果不能的话,直接把不能到的那几个数一数就行了 如果能的话: 可以发现(并不可以)某格能到达的最底下的格子一定是一个连续的区间 (因为如果不连续的话,我们先 ...
- [NOIP2010] 引水入城 贪心 + 记忆化搜索
---题面--- 题解: 本蒟蒻并没有想到bfs的做法,,,, 只会dfs了 首先我们需要知道一个性质. 我们设k[i].l 为在i点建立水库可以支援到的最左边的城市,k[i].r为最右边的. 那么点 ...
- 洛谷 1514 (NOIp2010) 引水入城
题目:https://www.luogu.org/problemnew/show/P1514 如果有解,一个第一行的格子能覆盖第n行的一定是一个连续的区间. 因为如果不连续,则有围住了一些第n行的格子 ...
- NOIP2010 引水入城 贪心+DFS
我们先把简单的不能搞死,具题意可证:每个蓄水长的管辖区域一定是连续的.证明:既然我们已经能了那么我们就可以说如果这个区间不是连续的那我们取出这个区间中间阻隔开的那一段,那么对于这一整个区间来说水源不可 ...
随机推荐
- 【转】./configure && make && make install详解
在Linux中利用源码包安装软件最重要的就是要仔细阅读安装包当中的README INSTALL两个说明文件,这两个文件会清楚的告诉你如何可以正确的完成这个软件的安装! 我们都知道源 ...
- C语言与MATLAB接口 编程与实例 李传军编着
罗列一下以前自己学习C语言与MATLAB混编的笔记,顺便复习一遍. <C语言与MATLAB接口 编程与实例 李传军编着>(未看完,目前看到P106) 目录P4-8 ************ ...
- Struts2 validate校验
一般的,用户注册的时候,我们需要校验一些用户提交过来的参数. 一般有两道屏障,一是在前台页面上使用js进行验证,直接杜绝了不正常信息的提交.二是将提交过来的信息进行验证,不通过则返回注册页面并显示错误 ...
- 跨域请求之jQuery的ajax jsonp的使用解惑
前天在项目中写的一个ajax jsonp的使用,出现了问题:可以成功获得请求结果,但没有执行success方法,直接执行了error方法提示错误——ajax jsonp之前并没有用过,对其的理解为跟普 ...
- Ajax返回类型JSON,XML
Ajax的三种返回类型 **一.TEXT *二.JSON 数据显示页面代码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transiti ...
- 关于java的static语句块
声明:转载请注明出处 static{}(即static块),会在类被加载的时候执行且仅会被执行一次,一般用来初始化静态变量和调用静态方法,下面我们详细的讨论一下该语句块的特性及应用. 一.在程序的一次 ...
- spark与Hadoop区别
2分钟读懂Hadoop和Spark的异同 2016.01.25 11:15:59 来源:51cto作者:51cto ( 0 条评论 ) 谈到大数据,相信大家对Hadoop和Apache Spark ...
- poj蚂蚁问题
问题描述: n只蚂蚁以每秒1cm的速度在长为Lcm的竿子上爬行.当蚂蚁爬到竿子的端点时就会掉落.由于竿子太细,两只蚂蚁相遇时,它们不能交错通过,只能各自反向 爬回去.对于每只蚂蚁,我们知道它距离竿子左 ...
- susy-Toolkit 之翻译
Toolkit工具包 The Susy 2.0 toolkit is built around our shorthand syntax. Use the shorthand to control e ...
- Mac环境下装node.js,npm,express
1. 下载node.js for Mac 地址: http://nodejs.org/ 直接下载 pkg的,双击安装,一路点next,很容易就搞定了. 安装完会提醒注意 node和npm的路径是 /u ...