main
黄海 1 year ago
parent d78217fa0c
commit b197ade7bc

@ -107,44 +107,49 @@ int res;
int main() { int main() {
cin >> n; cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i]; for (int i = 0; i < n; i++) cin >> a[i];
// 正向 // 正向
f[++fl] = a[1]; f[0] = a[0];
p1[1] = 1; p1[0] = 1;
for (int i = 2; i <= n; i++) for (int i = 0; i < n; i++)
if (a[i] > f[fl]) { if (a[i] > f[fl]) {
f[++fl] = a[i]; f[++fl] = a[i];
p1[i] = fl; p1[i] = fl;
} else { } else {
int t = lower_bound(f + 1, f + fl + 1, a[i]) - f; int t = lower_bound(f, f + fl, a[i]) - f;
f[t] = a[i]; f[t] = a[i];
p1[i] = t; p1[i] = t;
} }
// 反向 // 反向
g[++gl] = a[n]; g[0] = a[n - 1];
p2[n] = 1; p2[n - 1] = 1;
for (int i = n - 1; i >= 1; i--) for (int i = n - 1; i >= 0; i--)
if (a[i] > g[gl]) { if (a[i] > g[gl]) {
g[++gl] = a[i]; g[++gl] = a[i];
p2[i] = gl; p2[i] = gl;
} else { } else {
int t = lower_bound(g + 1, g + gl + 1, a[i]) - g; int t = lower_bound(g, g + gl, a[i]) - g;
g[t] = a[i]; g[t] = a[i];
p2[i] = t; p2[i] = t;
} }
for (int i = 1; i <= n; i++) res = max(res, p2[i] + p1[i] - 1); for (int i = 0; i < n; i++) res = max(res, p2[i] + p1[i] + 2 - 1);
printf("%d\n", res); printf("%d\n", res);
return 0; return 0;
} }
``` ```
### 六、状态机分析法 >**总结**
① 朴素版本性能较差$O(N^2)$,但有一个先天的优势:可以知道每个数字作为最高点时,左边有多少个,右边有多少个,对于求左右最长这样的题目不用再拐弯了。
② 贪心+二分版本的性能好$O(LogN*N)$,但有一个缺点,就是只能获取到最长上升序列的长度,不知道 **以每个数字为最高点时,左边有多少个,右边有多少个**,如果非得用这个算法不可的话,那么就需要对贪心+二分版本的代码进行改造:用数组记录第几个数字在上升序列中应该是排在第几位的,显得麻烦一些。
### 六、状态机分析法【选读$O(N^2)$】
这是我做过 $AcWing$第二场热身赛的$C$题——[$AcWing$ $3549$. 最长非递减子序列](https://www.acwing.com/problem/content/3552/) 后总结出来的一类模型 这是我做过 $AcWing$第二场热身赛的$C$题——[$AcWing$ $3549$. 最长非递减子序列](https://www.acwing.com/problem/content/3552/) 后总结出来的一类模型
那就是,**利用状态机模型$DP$解决最长$xxx$子序列模型** 的方法 那就是,**利用状态机模型$DP$解决最长$xxx$子序列模型** 的方法

@ -16,37 +16,37 @@ int res;
int main() { int main() {
cin >> n; cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i]; for (int i = 0; i < n; i++) cin >> a[i];
// 正向 // 正向
f[++fl] = a[1]; f[0] = a[0];
p1[1] = 1; p1[0] = 1;
for (int i = 2; i <= n; i++) for (int i = 0; i < n; i++)
if (a[i] > f[fl]) { if (a[i] > f[fl]) {
f[++fl] = a[i]; f[++fl] = a[i];
p1[i] = fl; p1[i] = fl;
} else { } else {
int t = lower_bound(f + 1, f + fl + 1, a[i]) - f; int t = lower_bound(f, f + fl, a[i]) - f;
f[t] = a[i]; f[t] = a[i];
p1[i] = t; p1[i] = t;
} }
// 反向 // 反向
g[++gl] = a[n]; g[0] = a[n - 1];
p2[n] = 1; p2[n - 1] = 1;
for (int i = n - 1; i >= 1; i--) for (int i = n - 1; i >= 0; i--)
if (a[i] > g[gl]) { if (a[i] > g[gl]) {
g[++gl] = a[i]; g[++gl] = a[i];
p2[i] = gl; p2[i] = gl;
} else { } else {
int t = lower_bound(g + 1, g + gl + 1, a[i]) - g; int t = lower_bound(g, g + gl, a[i]) - g;
g[t] = a[i]; g[t] = a[i];
p2[i] = t; p2[i] = t;
} }
for (int i = 1; i <= n; i++) res = max(res, p2[i] + p1[i] - 1); for (int i = 0; i < n; i++) res = max(res, p2[i] + p1[i] + 2 - 1);
printf("%d\n", res); printf("%d\n", res);
return 0; return 0;

Loading…
Cancel
Save