zoukankan      html  css  js  c++  java
  • CodeForces 4D

    我看了看大部分题解是按照 (mathcal{DP}) 做的呢。

    然鹅本羸弱根本对 (mathscr{DP}) 一窍不通。

    所以自己 (mathcal{YY}) 另一种清奇的做法。

    每次我们将两个符合条件的点 (x(i,j),y(i,j) (x_i<y_i,x_j<y_j)) 建一条边

    (x) 指向 (y)

    显然在把所有点加入后,至少存在一个点入度为零。

    所以我们只要拓扑排序,每次记录当前最长值,最后 (dfs) 输出方案就好了。

    值得注意的是: 这道题需要的空间比较大。 所以我们要使用邻接矩阵。

    因为邻接表是邻接矩阵空间的 (2) 倍加 (N) (记录一个点二倍, (head)(N)

    其次邻接矩阵类型要使用 (bool) ,不然照样 (mathcal{MLE})

    下面是 (mathcal{color{green}{AC}}) 代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <stack>
    #include <queue>
    using namespace std;
    #define ri register int
    
    bool mat[5002][5002];
    int len[5002], pre[5002], id[5002];
    int wf[5002], hf[5002], in[5002];
    int n, w, h, cnt, cnte, ans, fin;
    
    inline void topo()
    {
        queue<int> bf;
        for (ri i = 1; i <= cnt; ++i)
            if (in[i] == 0) bf.push(i), len[i] = 1;
        while (!bf.empty())
        {
            int now = bf.front();
            bf.pop();
            if (ans < len[now])
            {
                ans = len[now];
                fin = now;
            }
            for (ri i = 1; i <= cnt; ++i)
            {
                if (i == now || !mat[now][i]) continue;
                --in[i];
                if (len[i] < len[now] + 1)
                    len[i] = len[now] + 1, pre[i] = now;
                if (in[i] == 0)
                    bf.push(i);
            }
        }
    }
    
    void dfs(int p)
    {
        if (p == 0) return;
        if (pre[p]) dfs(pre[p]);
        printf("%d ", id[p]);
    }
    
    int main()
    {
        scanf("%d%d%d", &n, &w, &h);
        for (ri i = 1; i <= n; ++i)
        {
            int x, y;
            scanf("%d%d", &x, &y);
            if (x <= w || y <= h) continue;
            wf[++cnt] = x, hf[cnt] = y;
            id[cnt] = i;
        }
        if (cnt == 0)
        {
            printf("0
    ");
            return 0;
        }
        for (ri i = 1; i < cnt; ++i)
            for (ri j = i + 1; j <= cnt; ++j)
            {
                if (wf[i] < wf[j] && hf[i] < hf[j])
                    mat[i][j] = 1, ++in[j];
                else if (wf[i] > wf[j] && hf[i] > hf[j])
                    mat[j][i] = 1, ++in[i];
            }
        topo();
        printf("%d
    ", ans);
        dfs(fin);
        return 0;
    }
    
  • 相关阅读:
    BZOJ1233 干草堆
    POJ1321棋盘问题【搜索】
    1008
    10.2训练赛
    2014 ACM/ICPC Asia Regional Shanghai Online【未完成】
    hdu5045||2014 ACM/ICPC Asia Regional Shanghai Online【数位dp】
    0926
    poj1007【求逆序数】
    hlg1287数字去重和排序II【hash】
    hlgChocolate Auction【并查集】
  • 原文地址:https://www.cnblogs.com/Vty66CCFF/p/11839426.html
Copyright © 2011-2022 走看看