题解:
先一遍dfs看是否合法
若合法 则从上面任意一点到达下面的点一定是连续的 拓扑求出上面每点到下面的点的区间
把所有区间按头排序 贪心解决最少几个区间能覆盖全部区域之
代码:
1 #include2 #include 3 #include 4 using namespace std; 5 const int N=501; 6 struct info{ 7 int x,y; 8 info(const int a=0,const int b=0): 9 x(a),y(b){} 10 }map[N][N],qj[N],move[4]={info(1,0),info(-1,0),info(0,1),info(0,-1)}; 11 queue que; 12 int n,m,h[N][N],bo[N][N],bein[N][N],ans; 13 bool check(info x,info y){ return x.x+y.x>0 && x.y+y.y>0 && x.x+y.x<=n && x.y+y.y<=m; } 14 inline bool cmp(info a,info b){ return a.x<b.x; } 15 void search(info now){ 16 que.push(now); 17 bo[now.x][now.y]=1; 18 while (!que.empty()){ 19 now=que.front(); 20 que.pop(); 21 for (int i=0;i<4;i++) 22 if (check(now,move[i])) 23 if (!bo[now.x+move[i].x][now.y+move[i].y] && h[now.x][now.y]>h[now.x+move[i].x][now.y+move[i].y]){ 24 info ne=info(now.x+move[i].x,now.y+move[i].y); 25 bo[ne.x][ne.y]=1; 26 que.push(ne); 27 } 28 } 29 } 30 bool checkbo(){ 31 for (int i=1;i<=m;i++) 32 if (!bo[1][i]) search(info(1,i)); 33 for (int i=1;i<=m;i++) 34 if (!bo[n][i]) ++ans; 35 return ans; 36 } 37 void makebein(){ 38 for (int i=1;i<=n;i++) 39 for (int j=1;j<=m;j++) 40 for (int k=0;k<4;k++) 41 if (check(info(i,j),move[k])) 42 if (h[i][j] move[k].y]; 43 } 44 int max(int x,int y){ 45 if (!x) return y; 46 if (!y) return x; 47 return x>y ? x : y; 48 } 49 int min(int x,int y){ 50 if (!x) return y; 51 if (!y) return x; 52 return x x : y; 53 } 54 void makemap(){ 55 for (int j=1;j<=m;j++) map[n][j]=info(j,j); 56 for (int i=1;i<=n;i++) 57 for (int j=1;j<=m;j++) 58 if (!bein[i][j]) que.push(info(i,j)); 59 while (!que.empty()){ 60 info now=que.front(); 61 que.pop(); 62 for (int i=0;i<4;i++) 63 if (check(now,move[i])) 64 if (h[now.x][now.y] move[i].y]){ 65 info ne=info(now.x+move[i].x,now.y+move[i].y); 66 map[ne.x][ne.y].x=min(map[ne.x][ne.y].x,map[now.x][now.y].x); 67 map[ne.x][ne.y].y=max(map[ne.x][ne.y].y,map[now.x][now.y].y); 68 if (!--bein[ne.x][ne.y]) que.push(ne); 69 } 70 } 71 } 72 void makeqj(){ 73 makemap(); 74 for (int i=1;i<=m;i++) qj[i]=map[1][i]; 75 } 76 int getans(){ 77 sort(qj+1,qj+m+1,cmp); 78 int res=0; 79 for (int i=1,j=1;i<=m && j<=m;){ 80 ++res; 81 int x=0; 82 for (;qj[i].x<=j && i<=m;i++) 83 if (x qj[i].y; 84 j=x+1; 85 } 86 return res; 87 } 88 int main(){ 89 scanf("%d%d",&n,&m); 90 for (int i=1;i<=n;i++) 91 for (int j=1;j<=m;j++) scanf("%d",&h[i][j]); 92 if (checkbo()){ 93 printf("0\n%d",ans); 94 return 0; 95 } 96 makebein(); 97 makeqj(); 98 printf("1\n%d",getans()); 99 }