[AGC058B] Adjacent Chmax
我么采用区间染色思维去做这题(把 $P_i$ 看做一种颜色)。
钦定最终序列为 $P'$,以及 $l_i,r_i$ 分别为位置 $i$ 左右离 $i$ 最近的 $j$(满足 $P_j>P_i$)。
尝试思考每个颜色最后会覆盖到哪些位置。会发现 $[l_i,r_i]$ 其实就是 $i$ 能覆盖到的极大闭区间(区间内可以随意覆盖)。
这样的性质能比较方便我们去 $\text{DP}$。设 $f_{i,j}$ 表示考虑了原序列的前 $i$ 个位置的颜色,这 $i$ 种颜色已经覆盖了位置区间 $[1,j]$ 的方案数。
转移有两种:
- $f_{i,j}\leftarrow f_{i-1,j}$。
- $f_{i,j}\leftarrow f_{i,j-1}[l_i\leq j\leq r_i]$。
最终答案为 $f_{N,N}$。
时间复杂度 $O(N^2)$。
#include <bits/stdc++.h>
#define FL(i, a, b) for(int i = (a); i <= (b); i++)
#define FR(i, a, b) for(int i = (a); i >= (b); i--)
using namespace std;
typedef long long ll;
const int N = 5010;
const ll p = 998244353;
int n, a[N]; ll f[N];
int main(){
scanf("%d", &n), f[0] = 1;
FL(i, 1, n) scanf("%d", &a[i]);
FL(i, 1, n){
int l = i, r = i;
while(l > 1 && a[l - 1] < a[i]) l--;
while(r < n && a[r + 1] < a[i]) r++;
FL(j, l, r) (f[j] += f[j - 1]) %= p;
}
printf("%lld\n", f[n]);
return 0;
}