朴素LCIS的时间为O(n^3),优化以后实现了边走边算的过程,实际上是因为满足所有局部最优的情况下的全局最优,优化一维度实现了O(n^2)
//朴素LCIS O(n^3)
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define PII pair<int, int>
#define PLL pair<ll, ll>
const int N = 3010;
const int M = 2 * N;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const double PI = acos(-1.0);
const double eps = 1e-8;
int a[N], b[N];
int f[N][N];
//表示意义:所有由第一个序列的前i个字母,到第二个序列b[j]的公共上升子序列,该集合属性表示max
//那么可以讲f[i][j]看作两部分,一部分包含a[i],另一部分不包含a[i] -> f[i - 1][j](a[i] == b[j])
//对于包含a[i]的地方,我们对其进行最长上升子序列处理,盯准最后这个条件,看倒数第二个位置,去以b1,b2,·····bj结尾的序列max值
//遍历所有的,看看哪个最大
void solve()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int j = 1; j <= n; j++) cin >> b[j];
for(int i = 1; i <= n; i ++)
{
for(int j = 1; j <= n; j ++)
{
f[i][j] = f[i - 1][j];
if(a[i] == b[j])//满足公共
{
f[i][j] = max(f[i][j],1);
for(int k = 1; k < j; k ++)
{
if(b[k] < b[j])
{
f[i][j] = max(f[i][j],f[i][k] + 1);
}
}
}
}
}
int maxx = 0;
for (int i = 1; i <= n; i ++ )
{
maxx = max(maxx, f[n][i]);
}
cout << maxx << endl;
}
int main()
{
solve();
system("pause");
return 0;
}
换个角度来看,可以理解为把公共和上升分开来求,
//优化LCIS O(n^2)
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define PII pair<int, int>
#define PLL pair<ll, ll>
const int N = 3010;
const int M = 2 * N;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const double PI = acos(-1.0);
const double eps = 1e-8;
int a[N],b[N];
int f[N][N];
//表示意义:所有由第一个序列的前i个字母,到第二个序列b[j]的公共上升子序列,该集合属性表示max
//那么可以讲f[i][j]看作两部分,一部分包含a[i],另一部分不包含a[i] -> f[i - 1][j](a[i] == b[j])
//对于包含a[i]的地方,我们对其进行最长上升子序列处理,盯准最后这个条件,看倒数第二个位置,去以b1,b2,·····bj结尾的序列max值
//遍历所有的,看看哪个最大
void solve()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int j = 1; j <= n; j++) cin >> b[j];
for(int i = 1; i <= n; i ++)
{
int maxx = 1;
for(int j = 1; j <= n; j ++)
{
f[i][j] = f[i - 1][j];
if(a[i] == b[j])//满足公共
f[i][j] = max(f[i][j],maxx);
if(b[j] < a[i])//原来的b[k]<b[j],满足上升
maxx = max(maxx,f[i][j] + 1);//保存局部最优解,前缀最大值
}
}
int m = 0;
for(int i = 1; i <= n; i ++) m = max(m,f[n][i]);
cout << m << endl;
}
int main()
{
solve();
return 0;
}