以前一直以为是什么高端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】引水入城的更多相关文章

  1. 521. [NOIP2010] 引水入城 cogs

    521. [NOIP2010] 引水入城 ★★★   输入文件:flow.in   输出文件:flow.out   简单对比时间限制:1 s   内存限制:128 MB 在一个遥远的国度,一侧是风景秀 ...

  2. NOIP2010 引水入城

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

  3. NOIP2010引水入城[BFS DFS 贪心]

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

  4. NOIP2010 引水入城 题解

    http://www.rqnoj.cn/problem/601 今天发现最小区间覆盖竟然是贪心,不用DP!于是我又找到这题出来撸了一发. 要找到最上面每个城市分别能覆盖最下面哪些城市,如果最下面有城市 ...

  5. noip2010 引水入城 bfs+贪心

    如果能够实现,每个河边的城市对应的控制区域一定是一条线段. 所以直接bfs每个河边的城市,贪心线段的右端点 #include<cstdio> #include<cstring> ...

  6. Luogu1514 NOIP2010 引水入城 BFS、贪心

    传送门 NOIP的题目都难以写精简题意 考虑最上面一排的某一个点对最下面一排的影响是什么样的,不难发现必须要是一段连续区间才能够符合题意. 如果不是一段连续区间,意味着中间某一段没有被覆盖的部分比周围 ...

  7. luogu1514 [NOIp2010]引水入城 (bfs+记忆化搜索)

    我们先bfs一下看看是否能到最底下的所有点 如果不能的话,直接把不能到的那几个数一数就行了 如果能的话: 可以发现(并不可以)某格能到达的最底下的格子一定是一个连续的区间 (因为如果不连续的话,我们先 ...

  8. [NOIP2010] 引水入城 贪心 + 记忆化搜索

    ---题面--- 题解: 本蒟蒻并没有想到bfs的做法,,,, 只会dfs了 首先我们需要知道一个性质. 我们设k[i].l 为在i点建立水库可以支援到的最左边的城市,k[i].r为最右边的. 那么点 ...

  9. 洛谷 1514 (NOIp2010) 引水入城

    题目:https://www.luogu.org/problemnew/show/P1514 如果有解,一个第一行的格子能覆盖第n行的一定是一个连续的区间. 因为如果不连续,则有围住了一些第n行的格子 ...

  10. NOIP2010 引水入城 贪心+DFS

    我们先把简单的不能搞死,具题意可证:每个蓄水长的管辖区域一定是连续的.证明:既然我们已经能了那么我们就可以说如果这个区间不是连续的那我们取出这个区间中间阻隔开的那一段,那么对于这一整个区间来说水源不可 ...

随机推荐

  1. 创建plist文件

    可以先在工程中直接新建一个plist文件,往里面写入自己需要的数据.但是这里的plist文件我们无法修改,是只读的,我们可以将这个plist文件复制一份到沙盒中,然后对沙盒中的文件进行操作.具体代码如 ...

  2. MapReduce 重要组件——Recordreader组件

    (1)以怎样的方式从分片中读取一条记录,每读取一条记录都会调用RecordReader类: (2)系统默认的RecordReader是LineRecordReader,如TextInputFormat ...

  3. ButterKnife的配置

    1.打开settings选择Plugins 安装 安装完成后会提示重启AS. 2.在build.gradle文件中添加: compile 'com.jakewharton:butterknife:7. ...

  4. 乌龟棋(noip2010)

    分析:该题是经典的动态规划题目. 题目中涉及到卡片数.卡片分4类.格子数等若干信息,又每张卡片仅能使用一次.求到达终点最多能能获得多少分. 从题目中可知卡片的使用顺序影响最终得分,我们可知状态转移和使 ...

  5. 云计算平台简介(App Engine)

    云计算平台简介(App Engine)     1   简介 App Engine: 应用程序引擎,是托管网络应用程序的云计算平台. 1.1  什么是云 云计算通常简称为“云”,是一种通过 Inter ...

  6. (转)Tomcat的目录结构

    原文:http://hi.baidu.com/qinyougen/item/beeb506abb3e1d08a1cf0ffb Tomcat的目录结构 一.TOMCAT的目录结构 /bin:存放wind ...

  7. 关于binary search的一点解惑

    在写binary search时对于mid的计算我最开始使用的是 mid = (low + high)/2; 后来看到在很多的实现为 mid = low + (high - low)/2; 想了一下两 ...

  8. 15、C#基础整理(递归)

    带输出参数的函数 输入参数相当于函数而言,相当于已经赋值了的变量,直接可用输出参数相当于定义一个没有值的变量,在函数中进行赋值,然后调用函数的时候将赋值带出函数 例: public void shuc ...

  9. Application,Session,Cookie,ViewState和Cache区别

    在ASP.NET中,有很多种保存信息的内置对象,如:Application,Session,Cookie,ViewState和Cache等.下面分别介绍它们的用法和区别. 方法 信息量大小 作用域和保 ...

  10. GOLANG 反射法则

    译自[blog.golang.org/laws-of-reflection] 在计算机中, 反射是程序通过类型,检测到它自己的结构能力:是一种元编程程:也是一个具大的混淆点 在本文中,我们将通过解释反 ...