Disclaimer: This article is a blogger original article, follow the CC 4.0 BY-SA copyright agreement, reproduced, please attach the original source link and this statement.
Analysis
The key point of this question is that a very important conclusion:
each water plant in a continuous interval must be able to cover the bottom of
With this nature, we can get memory search leftmost point and the rightmost point of each water plant can cover, then greed can be covered at least segment
As for me, Han Han.
Just think of the n- 3 practices
for each water plant bfs, recording the lowest point reached under it
and then you can not do memory of, do not cover the line
would have been thinking about the idea of processing each store with a similar backpack water, but no progress and
fundamental research did not find that important properties of the above!
Code
#include<bits/stdc++.h>
#define in read()
#define re register
using namespace std;
inline int read(){
char ch;int f=1,res=0;
while((ch=getchar())<'0'||ch>'9') if(ch=='-') f=-1;
while(ch>='0'&&ch<='9'){
res=(res<<1)+(res<<3)+(ch^48);
ch=getchar();
}
return f==1?res:-res;
}
const int N=505;
int n,m,h[N][N],l[N][N],r[N][N];
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};
bool vis[N][N];
void DFS(int x,int y){
vis[x][y]=1;
for(re int i=0;i<4;++i){
int xx=x+dx[i];
int yy=y+dy[i];
if(xx<1||xx>n||yy<1||yy>m) continue;
if(h[xx][yy]>=h[x][y]) continue;
if(!vis[xx][yy]) DFS(xx,yy);
l[x][y]=min(l[x][y],l[xx][yy]);
r[x][y]=max(r[x][y],r[xx][yy]);
}
}
int main(){
n=in;m=in;
for(re int i=1;i<=n;++i) for(re int j=1;j<=m;++j) h[i][j]=in;
memset(l,127,sizeof(l));
memset(r,0,sizeof(r));
for(re int i=1;i<=m;++i) l[n][i]=r[n][i]=i;
for(re int i=1;i<=m;++i) if(!vis[1][i]) DFS(1,i);
int cnt=0;
for(re int i=1;i<=m;++i) if(!vis[n][i]) cnt++;
if(cnt){printf("0\n%d",cnt);return 0;}
int L=1,R=0;
while(L<=m){
for(re int i=1;i<=m;++i)
if(l[1][i]<=L) R=max(R,r[1][i]);
cnt++;
L=R+1;
}
printf("1\n%d",cnt);
return 0;
}