• noip 2010 引水入城 贪心 + 搜索


    不难分析出如果有解则每个蓄水厂所能覆盖到的干旱城市一定是连续的。否则,中间那些没被覆盖的部分永远都不能被覆盖到。
    当然,每个蓄水厂所覆盖的城市有可能不连续,不过既然有解,则一定都是连续的。我们可以开一个mark数组来记录每个城市是否被覆盖过,如果有没被覆盖到的,就统计没被覆盖到的数量,并输出无解。否则,就将问题转换成一个最小线段覆盖问题,排序一下再贪心即可。
    细节提示:一定要开记忆化搜索,不然会无限TLE(这TM不是P话)

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn = 500 + 5;
    int  n, m, mark[maxn], cnt;
    int st[maxn], ed[maxn], h[maxn][maxn], A[maxn];
    int vis[maxn][maxn];
    void dfs(int x,int y)
    {
        if(vis[y][x]) return ;
        vis[y][x] = 1;
        if(y == n)
        {
            int cur = x;
            mark[cur] = 1;
            while(cur > 1 && h[y][cur-1] < h[y][cur]) mark[cur-1] = 1, cur -= 1;
            st[cnt] = min(st[cnt],cur);
            cur = x;
            while(cur < m && h[y][cur+1] < h[y][cur]) mark[cur+1] = 1, cur += 1;
            ed[cnt] = max(ed[cnt],cur);
        }
        if(y - 1 >= 1 && h[y-1][x] < h[y][x]) dfs(x,y-1);
        if(y + 1 <= n && h[y+1][x] < h[y][x]) dfs(x,y+1);
        if(x - 1 >= 1 && h[y][x-1] < h[y][x]) dfs(x-1,y);
        if(x + 1 <= m && h[y][x+1] < h[y][x]) dfs(x+1,y);
    }
    bool cmp(int i,int j)
    {
        if(st[i] == st[j]) return ed[i] < ed[j];
        return st[i] < st[j];
    }
    int main()
    {
       // freopen("input.txt","r",stdin);
        scanf("%d%d",&n,&m);
        for(int i = 1;i <= n;++i)
            for(int j = 1;j <= m;++j)scanf("%d",&h[i][j]);
        for(int i = 1;i <= m;++i)
        {
            memset(vis,0,sizeof(vis));
            A[i] = cnt = i;
            st[cnt] = 1000, ed[cnt] = -1000;
            dfs(i,1);
        }
        int unwatered = 0;
        for(int i = 1;i <= m;++i)if(!mark[i]) ++ unwatered;
        if(unwatered > 0)
        {
            printf("0
    ");
            printf("%d",unwatered);
            return 0;
        }
        sort(A+1,A+1+m,cmp);
        int pre = 1, ans = 0, i = 0;
        while(pre < m)
        {
            while((st[A[i+1]] <= pre || st[A[i+1]] - pre == 1 )&& i < m)++i;
            ++ans;
            pre = ed[A[i]];
        }
        printf("1
    ");
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    git stash回退
    基于git tag快速修复
    Go语言开发规范
    defer实现原理
    string数据结构
    关于const iota
    struct
    map数据结构底层详解
    go 函数进阶
    go 内存分配原理
  • 原文地址:https://www.cnblogs.com/guangheli/p/9845206.html
Copyright © 2020-2023  润新知