ARC184D Erase Balls 2D 题解
Coffee_zzz · · 题解
将所有球按照
设选择的球所组成的集合为
设剩余的球所组成的集合为
- 对于
u \in f(S) 且x \not\in f(S) ,设a_j \lt u \lt a_{j+1} ,则显然有Y_{a_j}\gt Y_u \gt Y_{a_{j+1}} ; - 对于
v \not\in f(S) ,设a_j \lt v \lt a_{j+1} ,则显然有Y_{a_j} \lt Y_v 或Y_v \lt Y_{a_{j+1}} 。
直接对本质不同的
显然不漏容易做到,于是问题变成了如何做到不重。考虑把
-
- 对于任意
u \not\in T ,f\big(\{u\} \cup T\big) \ne f(S) ;换句话说,即再选择任意一个球都会导致f(T) 变化。
显然满足条件的集合
于是现在只需要统计有多少个集合
- 若存在
j \lt k \lt i ,使得对于任意j \lt u \lt k 都不满足Y_i \lt Y_u \lt Y_k 且对于任意k \lt v \lt i 都不满足Y_k \lt Y_v \lt Y_j (即选择k 不会导致f(T) 变化),则不能从j 转移到i ,否则可以从j 转移到i 。
于是做一个二维前缀和即可
const int N=305,mod=998244353;
int n,v[N],s[N][N],f[N];
void add(int &a,int b){
a+=b;
if(a>=mod) a-=mod;
}
bool check(int ax,int ay,int bx,int by){
return s[ax][ay]-s[ax][by-1]-s[bx-1][ay]+s[bx-1][by-1]==1;
}
void solve(){
cin>>n,s[1][n+2]++,s[n+2][1]++,v[1]=n+2,v[n+2]=1;
for(int i=1,x,y;i<=n;i++) cin>>x>>y,x++,y++,v[x]=y,s[x][y]++;
for(int x=1;x<=n+2;x++) for(int y=1;y<=n+2;y++) s[x][y]=s[x][y]+s[x-1][y]+s[x][y-1]-s[x-1][y-1];
f[1]=1;
for(int i=2;i<=n+2;i++){
for(int j=i-1;j>=1;j--){
if(v[j]<v[i]) continue;
bool flag=1;
for(int k=j+1;k<i;k++){
if(check(k,v[k],j,v[i])&&check(i,v[j],k,v[k])){
flag=0;
break;
}
}
if(flag) add(f[i],f[j]);
}
}
cout<<f[n+2]<<endl;
}