最长公共子序列:
经典的做法如下
#include <stdio.h>
#include <iostream>
#pragma warning(disable:4996);
using namespace std;
const int maxn = 1010;
int seq1[maxn];
int seq2[maxn];
int f[maxn][maxn] = { 0 };
int n;
int main()
{
scanf("%d", &n);
fill(f[0], f[0] + maxn * maxn, 0);
for (int i = 1; i <= n; i++)
{
scanf("%d", &seq1[i]);
}
for (int i = 1; i <= n; i++)
{
scanf("%d", &seq2[i]);
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
if (seq1[i] == seq2[j])
{
f[i][j] = max(f[i - 1][j - 1] + 1, f[i][j]);
}
else {
f[i][j] = max(max(f[i-1][j],f[i][j-1]), f[i][j]);
}
}
}
printf("%d", f[n][n]);
}
在这道题中,会被卡时间 1s只能运算1e7次,n2的复杂度,数据量又是1e5,肯定会超时间的。
前面那个模板可以直接套,这个解法的话就是比较巧妙了,利用了这比较的序列都是1-n的全排列的性质。
#include <stdio.h>
#include <iostream>
#include <map>
#include <vector>
#include <algorithm>
#pragma warning(disable:4996);
using namespace std;
const int maxn = 100010;
int n;
map<int, int> mp;
int seq2[maxn];
int main()
{
scanf("%d", &n);
int num;
for (int i = 1; i <= n; i++)
{
scanf("%d", &num);
mp[num] = i;
}
for (int i = 1; i <= n; i++)
{
scanf("%d", &num);
seq2[i] = mp[num];
}
int len = 1;
int up[maxn];
up[len] = seq2[1];
for (int i = 2; i <= n; i++)
{
if (seq2[i] > up[len])
{
up[++len] = seq2[i];
}
else {
int loc = upper_bound(up+1,up+len,seq2[i],less<int>()) - up;
up[loc] = seq2[i];
}
}
printf("%d", len);
}
|