-
最长上升子序列
-
定义
- 设有由(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)的不下降序列。
- 设有由(n)个不相同的整数组成的数列,记为: (b_1,b_2...b_n)且(b_i!=b_j(i!=j)),
-
(O(n^2))的做法
-
int lis(int a[], int n) { int f[N], ans = 0; for(int i = 1; i <= n; i++) f[i] = 1; for(int i = 1; i <= n; i++) { for(int j = 1; j < i; j++) if (a[j] < a[i] && f[i] < f[j] + 1) f[i] = f[j] + 1; ans = max(ans, f[i]); } return ans; }
-
(O(n log n))的做法
-
对于(n^2)的写法,状态是无法优化的,第二维是求(j~i)符合条件的最大子序列和
(b(i))定义为长度为(i)的最后一位数 -
看定义可能不太懂,
因为我就没看懂
看着挺复杂,其实也没啥,看代码注释吧
-
-
int lis(int a[], int n) { int f[N], cnt = 1; f[cnt] = a[1]; for(int i = 2; i <= n; i++) { if (a[i] > f[cnt]) f[++cnt] = a[i]; //求上升序列,如果a[i]比最后一位大,就在后面再添一个 else f[lower_bound(f+1, f+cnt+1, a[i])-f] = a[i]; //找到比他小的替换掉他 //upper_bound() 用到库<algorithm> //也可以手写二分 } return cnt; }
-
-
最长公共子串
-
定义
- 一列字符C既是A的子串,又是B的子串,就称C为A和B的公共子串
(这里子串指的是连续的)
- 一列字符C既是A的子串,又是B的子串,就称C为A和B的公共子串
-
(O(n^2))
-
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的公共子序列
(这里子序列可以不连续)
- 一列字符C既是A的子序列,又是B的子序列,就称C为A和B的公共子序列
-
(O(n^2))
-
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]为最后的结果
-
(O(nlogn))
- 没有重复数字的直接用离散化处理,有重复的用vector记录,放进b数组的时候按从后往前的顺序排列
-
无重复
-
scanf("%d", &n); tot = 0; for(int i = 1; i <= n; i++) scanf("%d", &a[i]), m[a[i]] = ++tot; for(int i = 1; i <= n; i++) scanf("%d", &b[i]), b[i] = m[b[i]]; tot = 0; s[++tot] = b[1]; for(int i = 2; i <= n; i++) { if (s[tot] < b[i]) s[++tot] = b[i]; else s[lower_bound(s+1, s+tot+1, b[i])-s] = b[i]; } printf("%d ", tot);
-
有重复
-
scanf("%d", &n); for (int i = 1, x; i <= n; i++) scanf("%d", &x), m[x].push_back(i); for (int i = 1, x; i <= n; i++) { scanf("%d", &x); for (int j = m[x].size()-1; j >= 0; j--) a[++len] = m[x][j]; } f[cnt=1] = a[1]; for (int i = 2; i <= len; i++) if (a[i] > f[cnt]) f[++cnt] = a[i]; else f[lower_bound(f+1, f+cnt+1, a[i])-f] = a[i]; printf("%d ", cnt);
-