题目
https://www.luogu.com.cn/problem/P1439
前言
之前在LeetCode做最长公共子序列是用dp来做的,今天看到洛谷这题,一口气上dp
只有区区50分,太丢脸了
简单分析一下,普通dp做法时间复杂度为O(n^2)
所以即使我用来滚动数组来做,时间还是会爆
因此我需要一种O(nlogn)的算法
题目分析
题目:……接下来两行,每行为 n 个数,为自然数 1,2,…,n 的一个排列。……
也就是说,在这个排列里,每个数只出现一次
思考
输入有两个排列,如果将第一个排列看作为规则,那么第二个排列在这个规则里求的是
最长公共子序列 既为 最长递增序列
搭配上洛谷的 递增
https://www.luogu.com.cn/problem/P3902
这道绿题的难度就降到黄题了
代码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
public class Main {
static int rule[],n,temp[],t,result=0;
public static void main(String[] args) throws IOException {
n=nextInt();
rule=new int[(int) (1e5+10)];//规则:每个数字对应的填的是 出现的位置
temp=new int[(int) (1e5+10)];
for (int i = 0; i < n; i++) {
rule[nextInt()]=i;//
}
temp[0]=rule[nextInt()];
for (int i = 1; i < n; i++) {
t=nextInt();
if(temp[result]<rule[t]) {
temp[++result]=rule[t];
}else {
temp[binarySearch(temp, result, rule[t])]=rule[t];
}
}
System.out.println(result+1);
}
static int binarySearch(int arr[],int r,int tar) {
int l=0,mid;
while(l<=r) {
mid=l+((r-l)>>1);
if(arr[mid]<=tar)
l=mid+1;
else
r=mid-1;
}
return l;
}
static BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
static StreamTokenizer st=new StreamTokenizer(in);
static double nextDouble() throws IOException {
st.nextToken();
return st.nval;
}
static int nextInt() throws IOException {
return (int)nextDouble();
}
}
结果
不仅过了,还骗了个榜首