cf463 D. Gargari and Permutations(DAG,dp)

题意:

给定m个长为n的排列,求它们的最长公共子序列

\(1\le n \le 1000,2\le m\le 5\)

思路:

建一个点数为n的图,\(j\)\(i\) 的后继当且仅当在所有排列中,\(j\) 都排在 \(i\) 的后面

然后dfs找最长路径

const int N = 1005, M = 6;
int n, m, p[M][N], f[N];

vector<int> G[N];

int dp(int u)
{
    if(f[u]) return f[u];
    for(int v : G[u]) f[u] = max(f[u], dp(v));
    return ++f[u];
}

main()
{
    cin >> n >> m;
    for(int i = 1; i <= m; i++)
        for(int j = 1, x; j <= n; j++)
            cin >> x, p[i][x] = j; //记录位置

    for(int i = 1; i <= n; i++) //建图
        for(int j = 1; j <= n; j++)
        {
            bool ok = 1;
            for(int k = 1; k <= m; k++)
            if(p[k][i] >= p[k][j]) {
                ok = 0;
                break;
            }
            if(ok) G[i].pb(j);
        }

    int ans = 0;
    for(int i = 1; i <= n; i++) ans = max(ans, dp(i));
    cout << ans;
}

posted @ 2022-02-15 10:59  Bellala  阅读(29)  评论(0)    收藏  举报