[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 } 
View Code

 

posted @ 2021-12-07 15:14  PYWBKTDA  阅读(183)  评论(0编辑  收藏  举报