zoukankan      html  css  js  c++  java
  • hdu 5495 LCS(并查集)

    Problem Description
    You are given two sequence {a1,a2,...,an} and {b1,b2,...,bn}. Both sequences are permutation of {1,2,...,n}. You are going to find another permutation {p1,p2,...,pn} such that the length of LCS (longest common subsequence) of {ap1,ap2,...,apn} and {bp1,bp2,...,bpn} is maximum. 
     
    Input
    There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:

    The first line contains an integer n(1n105) - the length of the permutation. The second line contains n integers a1,a2,...,an. The third line contains n integers b1,b2,...,bn.

    The sum of n in the test cases will not exceed 2×106.
     
    Output
    For each test case, output the maximum length of LCS.
     
    题意:给你两串数字然后让你求一个顺序使得这两个序列按这种顺序排列后LCS最大,并输出LCS的长度。
     
    由于这题的数据大用LCS肯定不行,枚举方案肯定也不行。但是由于可以随意移动且数字是1~n中的所有数,所以可以将关联的数字求出来,
    这些关联的数最大能组成len-2的LCS序列拿例题打个比方。
    6
    1 5 3 2 6 4
    3 6 2 4 5 1
    关联后可以得到
    (1-3-2-4-1),(5-6-5)
    1 3 2 4       5 6
    3 2 4 1       6 5
    所以组合后LCS就为(5-2)+(3-2)=4
    还有如果只有两个如(5-5)这时候加1就行
     
     
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    using namespace std;
    const int M = 1e5 + 10;
    int a[M] , b[M];
    int f[M] , va[M];
    void init(int n) {
        for(int i = 0 ; i <= n ; i++) {
            f[i] = i;
            va[i] = 1;
        }
    }
    int find(int x) {
        if(x != f[x])
            f[x] = find(f[x]);
        return f[x];
    }
    void Union(int x , int y) {
        int xx = find(x);
        int yy = find(y);
        if(xx != yy) {
            f[x] = yy;
            va[yy] += va[xx];
        }
    }
    int main()
    {
        int t;
        scanf("%d" , &t);
        while(t--) {
            int n;
            scanf("%d" , &n);
            init(M);
            for(int i = 0 ; i < n ; i++) {
                scanf("%d" , &a[i]);
            }
            for(int i = 0 ; i < n ; i++) {
                scanf("%d" , &b[i]);
                Union(a[i] , b[i]);
            }
            int count = 0;
            for(int i = 0 ; i < n ; i++) {
                if(f[a[i]] == a[i]) {
                    if(va[a[i]] == 1) {
                        count++;
                    }
                    else {
                        count += (va[a[i]] - 1);
                    }
                }
            }
            printf("%d
    " , count);
        }
        return 0;
    }
    
  • 相关阅读:
    安装AD域时,出现NetBIOS名称冲突?
    SharePoint Server 2010 安装图解
    Visual C++ 2011519
    Visual C++ 2011520
    Visual C++ 2011518
    Visual C++ 2011520
    设计模式创建型 C++版本
    线程条件变量,一次性初始化
    Visual C++ 2011526
    Visual C++ 2011512
  • 原文地址:https://www.cnblogs.com/TnT2333333/p/6053923.html
Copyright © 2011-2022 走看看