P1514 [NOIP2010 提高组] 引水入城

原题链接

考察:记忆化搜索

思路:

        注意这道题只需要覆盖最下面一行的点即可....对于每个第一行的点求出它能覆盖的最后一行的最左边和最右边.然后做区间覆盖即可.如果一个个点求会TLE.我们可以发现如果确定了一个点为起点,它能覆盖的左右端点都是确定的.所以可以用记忆化搜索.

        但是这道题如何标记搜过的点对程序的优化不同.如果以左右端点是否被更新来标记,在某个数据点会dfs109次....因为存在不能去最后一行的点.此时会不断搜索一遍.所以需要用bool数组标记.

 1 #include <iostream>
 2 #include <cstring>
 3 #include <queue>
 4 #include <algorithm>
 5 using namespace std;
 6 typedef pair<int,int> PII;
 7 const int N = 510;
 8 int n,m,mp[N][N],L[N][N],R[N][N];
 9 int xx[4] = {-1,1,0,0},yy[4] = {0,0,-1,1}; 
10 bool vis[N][N];
11 PII p[N];
12 void dfs(int x,int y)
13 {
14     if(vis[x][y]) return;
15     vis[x][y] = 1;
16     for(int i=0;i<4;i++)
17     {
18         int dx = x+xx[i],dy = y+yy[i];
19         if(dx>=1&&dx<=n&&dy>=1&&dy<=m&&mp[dx][dy]<mp[x][y])
20         {
21             if(!vis[dx][dy]) dfs(dx,dy);
22             L[x][y] = min(L[dx][dy],L[x][y]);
23             R[x][y] = max(R[dx][dy],R[x][y]);
24         }
25     }
26 }
27 void solve()
28 {
29     for(int i=1;i<=m;i++)
30     {
31         p[i].first = L[1][i];
32         p[i].second = R[1][i];
33     }
34     int ed = m,ans = 0,st = 1;
35     sort(p+1,p+m+1);
36     bool ok =1; 
37     for(int i=1,j=1;i<=m;i++)
38     {
39         int r = -2e9;
40         while(j<=m&&p[j].first<=st) r = max(p[j].second,r),j++;
41         if(r>=ed) {ans++;ok = 0;break;} 
42         if(r<st) {ans =-1;break;} 
43         st = r+1;
44         ans++;
45         i = j-1;
46     }
47     if(!ok) printf("1\n%d\n",ans);
48     else
49     {
50         int cnt = m;
51         for(int i=1;i<=m;i++)
52           cnt-=vis[n][i];
53         printf("0\n%d\n",cnt);
54     }
55 }
56 int main()
57 {
58     scanf("%d%d",&n,&m);
59     for(int i=1;i<=n;i++)
60       for(int j=1;j<=m;j++) scanf("%d",&mp[i][j]);
61     memset(L,0x3f,sizeof L); memset(R,-1,sizeof R);
62     for(int i=1;i<=m;i++) L[n][i] = i,R[n][i] = i;
63     for(int i=1;i<=m;i++) 
64       if(!vis[1][i]) dfs(1,i);
65     solve();
66     return 0;
67 }

 

posted @ 2021-04-13 08:51  acmloser  阅读(68)  评论(0编辑  收藏  举报