BestCoder Round #58 LCS 即hdu5495 (模拟)

LCS

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


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
 

Source
BestCoder Round #58 (div.2)
 

Recommend
hujie   |   We have carefully selected several similar problems for you:   5498  5497  5496  5495  5493 
 


解析:1.子序列的含义。这里的子序列与我们以前所认知的略有不同,是数学意义上的子序列。

在数学中,某个序列的子序列是从最初序列通过去除某些元素但不破坏余下元素的相对位置(在前或在后)而形成的新序列。 例如\{1,3,2\}{1,3,2}\{1, 4, 3, 5, 2, 1\}{1,4,3,5,2,1}的一个子序列.

           2.求环。BC的题解里就有一个求环,然后累加长度,更详细的解释就没了,这里就详细解释一下。

              对于每个a[i],b[i]有两种情况:

               ①b[i]==a[i]

                   在这种情况下,(<( ̄︶ ̄)> 你以为我要说什么?作为特例记下来就好)    

               ②b[i]!=a[i]

                   这种情况下,若a[i]要参与到最长子序列中,就只能是错位了。比如这样的一组数据:

                   1 3 2 4

                   3 2 4 1

                   错一位,变成这样:

                    1 3 2 4

                       3 2 4 1

                   最长子序列即为:3 2 4

                   这要怎么处理呢?

                   a1-->b3-->a3-->b2-->a2-->b4-->a4-->b1-->a1

                   也就是说,从数字 1 出发,通过A数列与B数列的一一对应关系,最终肯定会回到1,这就是一个环。在这个环中,A的长度==B的长度==4,子序列长度为3,这也就是为什么会有 L>1时,ans+=L-1。

           3.官方给的题解是,找到所有环L,若L==1(也就是a[i]==b[i]),ans+=1;若L>1,ans+=L-1。

              但实际上,由于两个数列都是从1到n的n个数,也就说两个数列必然是由 环 所组成。所以只要求出L>1的环的数量 J ,ans=n-J。  

代码:

#include
#include
#include
using namespace std;

const int maxn=1e5;
int a[maxn +10],b[maxn+10];
bool v[maxn+10];

int getin()
{
  int ans=0;char tmp;
  while(!isdigit(tmp=getchar()));
  do ans=(ans<<3)+(ans<<1)+tmp-'0';
  while(isdigit(tmp=getchar()));
  return ans;
}

int main()
{
  freopen("1.in","r",stdin);
  int t,n,ans,i,j,k;
  for(t=getin();t>0;t--)
    {
      ans=n=getin();
      for(i=1;i<=n;i++)a[i]=getin();
      for(i=1;i<=n;i++)b[a[i]]=getin();
      
      memset(v,0,sizeof(v));
      for(i=1;i<=n;i++)if(!v[i] && b[i]!=i)
        for(--ans,k=i;!v[k];k=b[k])v[k]=1;
	  printf("%d\n",ans);
	}
  return 0;
}


你可能感兴趣的:(BestCoder Round #58 LCS 即hdu5495 (模拟))