Back to Edit Distance(LCS + LIS)

Given 2 permutations of integers from 1 to N, you need to find the minimum number of operations necessary to change both or any one of them in such a way that they become exactly same. Here only two operations are allowed: either you can delete an integer from any position or you can insert an integer into any position, but replacing one integer by another one is not allowed. Say, N = 5 and the permutations are {1, 3, 5, 4, 2} and {1, 5, 4, 3, 2}. Then we need just 2 operations: we need to delete 3 from the 2nd position and insert it in the 4th position of the first permutation, or we can delete 3 from both the permutations, which also needs two operations.

Input

First line of the input contains a positive integer T (T ≤ 40). Each of the following T cases contains 3 lines for each case: the 1st line contains a single integer N (1 ≤ N ≤ 200, 000) and the next two lines contain the two permutations of the integers.

Output

For each case, print a line of the form ‘Case < x >: < y >’, where x is the case number and y is the number of operations necessary to covert the 1st permutation to the 2nd permutation.

Sample Input

2 5 1 3 5

4 2 1 5 4

3 2 4 1 2

4 3 3 4 2 1

Sample Output

Case 1: 2

Case 2: 6

 

#include<bits/stdc++.h>
using namespace std;
const int M = 2e5 + 10 , inf = 0x3f3f3f3f;
int n ;
int orm[M] ;
int a[M] ;
int Top[M] ;
int judge (int x) {
        int l = 0 , r = n ; 
        int ret = l ;
        while (l <= r) {
                int mid = l+r >> 1 ;
                if (x > Top[mid]) {
                        ret = mid ;
                        l = mid+1 ;
                }
                else r = mid-1 ;
        }
        Top[ret+1] = min (Top[ret+1] , x) ;
        return ret+1 ;
}

int LIS () {
        int ans = 0 ;
        for (int i = 1 ; i <= n ; i ++) {
                ans = max (ans , judge (a[i])) ;
        }
        return ans ;
}

int main () {
        int T ;
        scanf ("%d" , &T ) ;
        for (int cas = 1 ; cas <= T ; cas ++) {
                scanf ("%d" , &n) ;
                for (int i = 1 ; i <= n ; i ++) {
                        int x ;
                        scanf ("%d" , &x) ;
                        orm[x] = i ;
                        Top[i] = inf ;
                }
                for (int j = 1 ; j <= n ; j ++) {
                        int x ;
                        scanf ("%d" , &x) ;
                        a[j] = orm[x] ;
                }
                printf ("Case %d: %d\n" , cas , (n-LIS ())*2) ;
        }
        return 0 ;
}

  要灵活运用他是一个1~n的排列。

然后你就能把lcs变成lis了。

转载于:https://www.cnblogs.com/get-an-AC-everyday/p/4761763.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值