0
点赞
收藏
分享

微信扫一扫

AtCoder Beginner Contest 217 F - Make Pair (区间dp)


​​linkkkkk​​​ 题意:
个数,给出对关系表示a-b有联系。每次将这些数排成一排,如果相邻两个数有联系的话就可以消去,求方案数。
思路:
表示将之间的数消去的方案数。
枚举中间点的时候,假设有联系,那么区间就可以分为两段,贡献是

如果两个数之间的数的个数是奇数的话,这两个数之间有联系也是对答案没有影响的;同理枚举的时候也要保证分出来的两段区间是偶数个数。
代码:

,m,dp[2100][2100];
bool vis[2100][2100];
vector<int>g[1100];
ll c[2100][2100];

void init(){
for(int i=0;i<2100;i++)
for(int j=0;j<=i;j++){
if(j==0) c[i][j]=1;
else c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
}
}

int main() {
init();
n=read,m=read;
rep(i,1,m){
int u=read,v=read;
if((v-u-1)%2) continue;
vis[u][v]=1;
if(abs(u-v)==1){
dp[u][v]=dp[v][u]=1;
}
}
for(int len=2;len<=2*n;len+=2){
for(int l=1;l+len-1<=2*n;l++){
int r=l+len-1;
if(vis[l][r]) dp[l][r]=dp[l+1][r-1];
for(int k=l+2;k<r;k+=2)
if(vis[k][r]){
dp[l][r]=(dp[l][r]+dp[l][k-1]*dp[k+1][r-1]%mod*c[(r-l+1)/2][(k-l)/2]%mod)%mod;
}
//cout<<dp[l][r]<<endl;
}
}

printf("%lld\n",dp[1][2*n]);

return 0;
}


举报

相关推荐

0 条评论