第一行包含一个整数N,表示数列A,B的长度。
第二行包含N个整数,表示数列A。
第三行包含N个整数,表示数列B。
输出一个整数,表示最长公共上升子序列的长度。
1≤N≤3000,序列中的数字均不超过231?1
状态表示:f[i][j]表示A数组中的前i个元素以及B数组的前j个元素,且以B[j]结尾的最长公共上升子序列
状态计算:分情况讨论,当A[i]不包含在LICS中时,那么f[i][j] == f[i-1][j]
当A[i]包含在LICS中时,由于B[j]是结尾元素,那么一定有A[i]==B[j],然后遍历1~j的所有元素k,当B[j] > B[k]时,f[i][j] == max(f[i][j], f[i-1][k] + 1)
Code: O(n3)
#include <bits/stdc++.h>
using namespace std;
const int N = 3010;
int n;
int a[N],b[N];
int f[N][N];
int main()
{
cin >> n;
for(int i = 1;i <= n;i++) cin >> a[i];
for(int i = 1;i <= n;i++) cin >> b[i];
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-1][k] + 1);
}
}
}
int ans = 0;
for(int i = 1;i <= n;i++) ans = max(ans, f[n][i]);
cout << ans << endl;
return 0;
}
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] < a[i])
f[i][j] = max(f[i][j], f[i-1][k] + 1);
}
}
}
for(int i = 1;i <= n;i++)
{
int maxv = 0;
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], maxv + 1);
if(b[j] < a[i]) maxv = max(maxv,f[i][j]);
}
}
#include <bits/stdc++.h>
using namespace std;
const int N = 3010;
int a[N],b[N];
int f[N];
int main()
{
int n;
cin >> n;
for(int i = 1;i <= n;i++) cin >> a[i];
for(int i = 1;i <= n;i++) cin >> b[i];
for(int i = 1;i <= n;i++)
{
int maxv = 0;
for(int j = 1;j <= n;j++)
{
if(a[i] == b[j]) f[j] = max(f[j], maxv + 1);
if(b[j] < a[i]) maxv = max(maxv,f[j]);
}
}
int ans = 0;
for(int i = 1;i <= n;i++) ans = max(ans, f[i]);
cout << ans << endl;
return 0;
}
原文:https://www.cnblogs.com/zcxy/p/13059027.html