D - Prince and Princess

https://vjudge.net/contest/221630#problem/D
这个题目是公主和王子都从(0,0)走到(n,n),只不过路径不完全相同,让你找出两人的最大可以共同走过的地方。

Sample Input

1
3 6 7
1 7 5 4 8 3 9
1 4 3 5 6 2 8 9

Sample Output

Case 1: 4

解题思路:
这个题其实是其最长公共子串问题,但是因为题目是255*255的,如果按照LCS算法进行得话,时间复杂度为(255*255)^2,会超时,所以改成求最大上升子序列。
数列a和数列b
将数列b中的数按其在数列a中出现的顺序重新编号,a中没有的则不记录
如a: 1 7 5 4 8 3 9
b: 1 4 3 5 6 2 8 9 重新编号后: 0 3 6 2 4 6
然后求b的最长上升子序列。因为求最长上升子序列的时间复杂度依然为n^2,但是可以改进,使用二分法来求第一个大于num的下标,故可以将时间复杂度减小为(nlogn)。
dp[n]始终保持上升子列长度为n的最后一位数(越小越好)保持最小值。

#include <iostream>
#include <bits/stdc++.h>
using namespace std;

int num[255*255],bnum[255*255],dp[255*255];
int n,p,q;

int find(int i,int j,int num){//二分法找到dp[]中第一个大于num的那个数的下标 
    while(i<j){
        int mid=(i+j)/2;
        if(dp[mid]>num) j=mid;
        else i=mid+1;
    }
    return j;
}
int main(){
    int t;
    cin>>t;
    int tt=0;
    while(t--){
        tt++;
        cin>>n>>p>>q;
        int sa,sb;
        memset(num,-1,sizeof(num));
        memset(bnum,0,sizeof(bnum));
        memset(dp,0,sizeof(dp));
        for(int i=0;i<=p;i++){
            cin>>sa;
            num[sa]=i;
        }
        int m=0;
        for(int i=0;i<=q;i++){
            cin>>sb;
            if(num[sb]!=-1)
                bnum[m++]=num[sb];
        }
        dp[1]=bnum[0];
        int k=1,mid;
        for(int i=1;i<m;i++){
            if(bnum[i]>dp[k]) dp[++k]=bnum[i];
            else{
                mid=find(0,k,bnum[i]);
                dp[mid]=bnum[i];
            } 
        }
        printf("Case %d: %d\n",tt,k);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值