标签:字符 ret 为我 pre 线性 公共子串 定义 最长公共子序列 复杂
设有由\(n\)个不相同的整数组成的数列,记为: \(b_1,b_2...b_n\)且\(b_i!=b_j(i!=j)\),
若存在\(i_1<i_2<...<i_n\)且有\(b_{i_1}<b_{i_2}...<b_{i_3}\)则称为长度为\(e\)的不下降序列。
for(int i = 1, m; i <= n; i++) {
m = 0;
scanf("%d", &a[i]);
for(int j = 1; j < i; j++)
if (a[j] < a[i] && s[j] >m)
m = s[j];
s[i] = m + 1;
if (s[i] > ans) ans = s[i];
}
对于\(n^2\)的写法,状态是无法优化的,第二维是求\(j~i\)符合条件的最大子序列和
\(b(i)\)定义为长度为\(i\)的最后一位数
看定义可能不太懂~~因为我就没看懂~~
看着挺复杂,其实也没啥,看代码注释吧
int lis(int a[], int n) {
int b[N], cnt = 1;
b[cnt] = a[1];
for(int i = 2; i <= n; i++) {
if (a[i] >= b[cnt]) b[++cnt] = a[i];
//求上升序列,如果a[i]比最后一位大,就在后面再添一个
else b[upper_bound(b+1, b+cnt+1, a[i])-b] = a[i];
//找到比他小的替换掉他
//upper_bound() 用到库<algorithm>
//也可以手写二分
}
return cnt;
}
一列字符C既是A的子串,又是B的子串,就称C为A和B的公共子串
(这里子串指的是连续的)
scanf("%s %s", a+1, b+1);
n = strlen(a+1); m = strlen(b+1);
for(int i = 1; i <= n; i++)
for(int j = m; j > 0; j--) {
if (a[i] == b[j])
s[j] = s[j-1] + 1, ans = max(ans, s[j]);
else s[j] = 0;
}
一列字符C既是A的子序列,又是B的子序列,就称C为A和B的公共子序列
(这里子序列可以不连续)
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
if (a[i] == b[j]) f[i][j] = f[i-1][j-1] + 1;
else f[i][j] = max(f[i-1][j], f[i][j-1]);
//f[n][n]为最后的结果
标签:字符 ret 为我 pre 线性 公共子串 定义 最长公共子序列 复杂
原文地址:https://www.cnblogs.com/Z8875/p/13178985.html