[atAGC056B]Range Argmax
对于一组合法的$\{x_{i}\}$,取最小的$k$使得$\forall k\in [l_{i},r_{i}],x_{i}=k$,其中$k$存在性显然
进一步的,考虑枚举$k$并求对应于这个$k$的合法$\{x_{i}\}$数量,$\{x_{i}\}$条件即:
1.$\forall k\in [l_{i},r_{i}],x_{i}=k$且不存在$1\le k'<k$满足此条件
2.合法性,且显然存在对应的$\{p_{i}\}$使得$p_{k}=n$,这就保证条件在$k\in [l_{i},r_{i}]$时成立,同时剩下的区间即可以被分为$[1,k)$和$(k,n]$两个子问题
(子问题$[L,R]$指仅考虑$[l_{i},r_{i}]\subseteq [L,R]$的区间)
对两个子问题分别处理:
1.$(k,n]$这个子问题与第1个条件无关,直接利用区间dp求出即可
2.$[1,k)$这个子问题与第1个条件结合,考虑其对应的$k'$,即要存在区间同时包含$k$和$k'$
换言之,记$mn$为包含$k$的区间最小左端点,即要求$k'\ge mn$
综合上述分析,不难得到以下做法——
令$f_{L,R,t}$表示$[L,R]$这个子问题中对应的$k\ge t$的合法$\{x_{i}\}$数量,转移即
$$
f_{L,R,t}=\sum_{k=t}^{R}f_{L,k-1,mn_{L,R,k}}f_{k+1,R,k+1}=f_{L,R,t+1}+f_{L,t-1,mn_{L,R,t}}f_{t+1,R,t+1}
$$
(其中$mn_{L,R,k}$为$[L,R]$这个子问题中包含$k$的区间最小左端点,可以$o(n^{3})$预处理出来)
时间复杂度为$o(n^{3})$,可以通过
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 305 4 #define mod 998244353 5 #define ll long long 6 int n,m,x,y,vis[N][N],mn[N][N][N],f[N][N][N]; 7 int main(){ 8 scanf("%d%d",&n,&m); 9 for(int i=1;i<=m;i++){ 10 scanf("%d%d",&x,&y); 11 vis[x][y]=1; 12 } 13 for(int i=n;i;i--) 14 for(int j=i;j<=n;j++) 15 for(int k=i;k<=j;k++){ 16 mn[i][j][k]=k; 17 if (i<k)mn[i][j][k]=min(mn[i][j][k],mn[i+1][j][k]); 18 if (k<j)mn[i][j][k]=min(mn[i][j][k],mn[i][j-1][k]); 19 if (vis[i][j])mn[i][j][k]=i; 20 } 21 for(int i=0;i<=n;i++)f[i+1][i][i+1]=1; 22 for(int i=n;i;i--) 23 for(int j=i;j<=n;j++){ 24 int s=0; 25 for(int k=j;k>=i;k--){ 26 s=(s+(ll)f[i][k-1][mn[i][j][k]]*f[k+1][j][k+1])%mod; 27 f[i][j][k]=s; 28 } 29 } 30 printf("%d\n",f[1][n][1]); 31 return 0; 32 }