[ABC217F] Make Pair 讲解
题目
考察:区间 dp,组合数。
状态与边界条件:
我们设
转移方程:
对于每一个
接下来我们需要找到一个点(同学)
就是下面这张图(paint 画图有点丑):
若只是将
对于整个
那么我们得到最后的转移方程:
当然,我们得保证
代码:
#include<bits/stdc++.h>
#define int long long
#define inl inline
#define reg register
#define INF 214748364721474836
using namespace std;
inl int read(){
int f=1,x=0;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return f*x;
}
inl void write(int x){
if(x<0){
x=-x;
putchar('-');
}
if(x>=10) write(x/10);
putchar(x%10^48);
}
#define MOD 998244353
#define N 405
int n,m,u,v,f[N][N],c[N][N];
bool vis[N][N];
signed main(){
n=read()<<1;
m=read();
for(int i=1;i<=m;++i){
u=read();
v=read();
if((u^v)&1) vis[u][v]=vis[v][u]=true;
}
for(int i=0;i<=n;++i) f[i+1][i]=1;
for(int i=0;i<=n;++i)
for(int j=0;j<=i;++j)
if(j==0) c[i][j]=1;
else c[i][j]=(c[i-1][j]+c[i-1][j-1])%MOD;
for(int len=2;len<=n;len+=2)
for(int l=1;l+len-1<=n;++l){
int r=l+len-1;
if(vis[l][r]) f[l][r]=f[l+1][r-1];
for(int k=l+2;k<r;k+=2)
if(vis[k][r]) f[l][r]=(f[l][r]+(f[l][k-1]*f[k+1][r-1]%MOD)*c[len>>1][(r-k+1)>>1]%MOD)%MOD;
}
write(f[1][n]%MOD);
return 0;
}