最长上升子序列【模板】
作者:互联网
P1439 【模板】最长公共子序列 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
- n^2的最长上升子序列解法
#include<iostream>
using namespace std;
int dp[1001][1001],a1[2001],a2[2001],n,m;
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)scanf("%d",&a1[i]);
for(int i=1;i<=m;i++)scanf("%d",&a2[i]);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
if(a1[i]==a2[j])
dp[i][j]=max(dp[i][j],dp[i-1][j-1]+1);
}
cout<<dp[n][m];
}
- 本题需要降低到nlogn,因为两个序列里的元素都是相同数的排列,所以可以用最长上升子序列求(nlogn)
- 把a数组的数映射成1到n,然后队b数组取了映射的结果求最长上升子序列就行
- 求最长上升子序列只需把新迭代到的数找到对应位置插入,该位置为答案序列(也就是当前最优的上升子序列)中大于或等于这个新数的最小的位置(第一个),用lower_bound直接求出
#include <bits/stdc++.h>
using namespace std;
#define N 1e5
#define INF 2e9
#define MAX 1000000
// https://www.luogu.com.cn/problem/P1439
int n;
int mapp[MAX], ans[MAX];
int main()
{
cin >> n;
for (int i = 1, t; i <= n; i++)
{
scanf("%d", &t);
mapp[t] = i;
}
memset(ans, 0x3f3f3f, sizeof(ans));
for (int i = 1, t; i <= n; i++)
{
scanf("%d", &t);
t = mapp[t];
*lower_bound(ans + 1, ans + n + 1, t) = t;
}
printf("%d", lower_bound(ans + 1, ans + n + 1, ans[0]) - ans - 1);
}
标签:int,MAX,序列,上升,最长,模板,define 来源: https://www.cnblogs.com/Wang-Xianyi/p/16632649.html