• Luogu 1514 [NOIP2010] 引水入城


    我就是过来开心一下……这道题从开坑以来已经堆积了大半年了……今天才发现广搜一直写挂……

    丢个线段覆盖的模板,设$f_{i}$表示覆盖区间[1, i]的最小代价,$g_{i, j}$表示覆盖区间[i, j]的代价,有转移方程

                                  $f_{i} = f_{j} + g_{j + 1, i}$   $(0 < j < i)$

    这道题直接暴力跑转移就可以了,但是对于一些n比较大的题,可以写一个前向星或者是vector存右端点一样的线段,这样子会快很多

    还有要注意n = 1的坑点

    放个提交记录给自己警示一下!https://www.luogu.org/recordnew/lists?uid=60553&pid=1514

    Code:

    #include <cstdio>
    #include <queue>
    #include <cstring>
    using namespace std;
    
    const int N = 505;
    const int dx[] = {-1, 1, 0, 0}, dy[] = {0, 0, 1, -1};
    const int inf = 0x3f3f3f3f; 
    
    int n, m, a[N][N], f[N], g[N][N], ran[N][2], tot = 0, head[N];
    bool cov[N], vis[N], vis2[N][N];
    
    struct Segment {
        int ln, nxt;
    } s[N];
    
    inline void add(int ln, int rn) {
        s[++tot].ln = ln;
        s[tot].nxt = head[rn];
        head[rn] = tot;
    }
    
    inline void read(int &X) {
        X = 0;
        char ch = 0;
        int op = 1;
        for(; ch > '9' || ch < '0'; ch = getchar())
            if(ch == '-') op = -1;
        for(; ch >= '0' && ch <= '9'; ch = getchar())
            X = (X << 3) + (X << 1) + ch - 48;
        X *= op;
    }
    
    inline int max(int x, int y) {
        return x > y ? x : y;
    }
    
    inline int min(int x, int y) {
        return x > y ? y : x;
    }
    
    struct Node {
        int x, y;
    };
    queue <Node> Q;
    
    inline bool vivid(Node now) {
        return now.x >= 1 && now.x <= n && now.y >= 1 && now.y <= m;
    }
    
    void bfs(int fir) {    
        memset(vis2, 0, sizeof(vis2));
        vis2[1][fir] = 1;
        int ln = inf, rn = -inf;
        Q.push((Node) {1, fir});
        if(n == 1) {
            cov[fir] = 1;
            ln = rn = fir;
        }
        
        vis[fir] = 1;
        
        for(; !Q.empty(); ) {
            Node out = Q.front(); Q.pop();
            for(int i = 0; i < 4; i++) {
                Node in = (Node) {out.x + dx[i], out.y + dy[i]};
                if(vivid(in) && a[out.x][out.y] > a[in.x][in.y] && !vis2[in.x][in.y]) {
                    if(in.x == 1) vis[in.y] = 1;
                    if(in.x == n) {
                        cov[in.y] = 1;
                        ln = min(ln, in.y);
                        rn = max(rn, in.y);
                    }
                    vis2[in.x][in.y] = 1;
                    Q.push(in);
                }
            } 
        }
    //    printf("%d %d %d
    ", fir, ln, rn);
        if(ln > rn) return;
        
        for(int i = ln; i <= rn; i++) {
            for(int j = i; j <= rn; j++) {
                g[i][j] = 1;
                if(i == 1) f[j] = 1;
            }
        }
    }
    
    int main() {
    //    freopen("1.in", "r", stdin); 
        
        read(n), read(m);
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= m; j++)
                read(a[i][j]);
        memset(g, 0x3f, sizeof(g));
        memset(f, 0x3f, sizeof(f));
        for(int i = 1; i <= m; i++) 
            if(!vis[i]) bfs(i);
            
        int cnt = 0;
        for(int i = 1; i <= m; i++) 
            if(!cov[i]) cnt++;
            
        if(cnt > 0) {
            printf("0
    %d
    ", cnt);
            return 0;
        }
        
    /*    for(int i = 1; i <= m; i++)
            printf("%d ", f[i]);
        printf("
    ");   */
        
        for(int i = 1; i <= m; i++)
            for(int j = 1; j <= i; j++) 
                f[i] = min(f[i], f[j] + g[j + 1][i]);
        printf("1
    %d
    ", f[m]);
        
        return 0;
    }
  • 相关阅读:
    4.程序员那点事-遭窃
    3.程序员那点事-惭愧与无奈
    2.程序员那点事-迷惘与憧憬
    1.程序员那点事-抉择
    6月22日の勉強レポート
    6月20日の勉強レポート
    6月16日の勉強レポート
    6月15日の勉強レポート
    IOSアプリケーション開発環境の構築
    iOSシステム構成の纏め
  • 原文地址:https://www.cnblogs.com/CzxingcHen/p/9470148.html
Copyright © 2020-2023  润新知