hdoj 5495 LCS 【统计元素个数大于1的置换群数目】【LCS变形】



LCS

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 23    Accepted Submission(s): 12


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  nintegers  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.
 

Sample Input
 
       
2 3 1 2 3 3 2 1 6 1 5 3 2 6 4 3 6 2 4 5 1
 

Sample Output
 
       
2 4
 



题意:给两个由1~n组成的n个数序列a[]和b[],让你找到一个1~n的序列p[],使得a[p[1]] , a[p[2]] ... a[p[n]]  和 b[p[1]], b[p[2]]... b[p[3]]的LCS最大,输出最大的LCS。


分析:对于一个有n个元素的置换群,我们可以付出一个元素的代价得到n-1长度的LCS。

思路:统计元素个数大于1的置换群个数ans,答案就是 n - ans。为了方便可以用pos[i]记录a或b序列中元素i所在的位置。


AC代码:


#include 
#include 
#include 
#define MAXN 100000+10
using namespace std;
struct rec
{
    int a, b;
};
rec num[MAXN];
bool vis[MAXN];
int pos[MAXN];
int main()
{
    int t, n;
    scanf("%d", &t);
    while(t--)
    {
        scanf("%d", &n);
        for(int i = 0; i < n; i++)
        {
            scanf("%d", &num[i].a);
            pos[num[i].a] = i;
        }
        //int cnt = 0;
        for(int i = 0; i < n; i++)
        {
            scanf("%d", &num[i].b);
//            if(num[i].a == num[i].b)
//                cnt++;
        }
        memset(vis, false, sizeof(vis));
        int ans = 0;
        for(int i = 0; i < n; i++)
        {
            if(vis[num[i].a]) continue;
            int j = num[i].b;
            int have = 1;
            while(j != num[i].a)
            {
                vis[j] = true;
                int next = pos[j];
                have++;
                j = num[next].b;
            }
            ans += have > 1 ? 1 : 0;
            //ans = max(have, ans);
        }
        printf("%d\n", n-ans);
    }
    return 0;
}


你可能感兴趣的:(DP之LCS,置换群poyla)