zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    [转] jQuery 操作 JSON 数据
    [转] 8张图学习javascript
    HTML文档类型声明的坑...
    Android 应用内HttpClient 与 WebView 共享 Cookie
    李嘉诚无锡演讲
    keytool 生成 Android SSL 使用的 BKS
    LeetCode-344-反转字符串
    LeetCode-342-4的幂
    LeetCode-338-比特位计数
    LeetCode-326-3的幂
  • 原文地址:https://www.cnblogs.com/guangheli/p/9845206.html
Copyright © 2011-2022 走看看