zoukankan      html  css  js  c++  java
  • AGC030F

    https://atcoder.jp/contests/agc030/tasks/agc030_f

    题解

    我们先把这个排列从(1 sim 2n)表达出来,然后题面中的每一对数我们可以用一条线把他们连起来,那么在序列中表达出的值是这条线的左端点。

    如果一开始每个数都没有限制的话,我们则需要求有哪些数会成为左端点,这个其实就是卡特兰数,求答案的话还需要求一个阶乘。

    现在有一些位置有了限制,我们就把有限制的位置成为特殊位置。

    还是从(1sim 2n)这个序列上考虑,因为我们的贡献是在左端点产生,所以我们设(dp[i][j][k])表示做到(i),有(j)个普通点没有被匹配,有(k)个特殊点没有被匹配。

    普通点可以任意匹配,特殊点只能匹配普通点。

    如果普通点匹配了特殊点,那么它的位置已经确定了,所以最后我们要乘上普通配普通的对数的阶乘。

    代码

    #include<bits/stdc++.h>
    #define N 602
    using namespace std;
    typedef long long ll;
    int n,now,a[N],sm;
    int tag[N];
    ll jie[N],dp[2][302][302];
    const int mod=1e9+7;
    inline void MOD(ll &x){x=x>=mod?x-mod:x;}
    inline ll rd(){
        ll x=0;char c=getchar();bool f=0;
        while(!isdigit(c)){if(c=='-')f=1;c=getchar();}
        while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
        return f?-x:x;
    }
    int main(){
        n=rd();
        sm=n*2;
        int cnt=0;
        for(int i=1;i<=sm;++i){
            a[i]=rd();
            if(a[i]!=-1)tag[a[i]]=1;
            if(i%2==0&&a[i]!=-1&&a[i-1]!=-1){
                tag[a[i]]=-1;
                tag[a[i-1]]=-1;
            }
            if(i%2==0&&a[i]==-1&&a[i-1]==-1)cnt++;
        }
        jie[0]=1;
        for(int i=1;i<=sm;++i)jie[i]=jie[i-1]*i%mod;
        dp[1][0][0]=1;
        int now=1,pre=0;
        for(int i=sm;i>=1;--i)if(tag[i]!=-1){
            swap(now,pre);
            memset(dp[now],0,sizeof(dp[now]));
            for(int j=0;j<=n;++j)
                for(int k=0;j+k<=n;++k)if(dp[pre][j][k]){
                    if(tag[i]){
                      MOD(dp[now][j][k+1]+=dp[pre][j][k]);
                      if(j)MOD(dp[now][j-1][k]+=dp[pre][j][k]);
                    }
                    else{
                      MOD(dp[now][j+1][k]+=dp[pre][j][k]);
                      if(j)MOD(dp[now][j-1][k]+=dp[pre][j][k]);
                      if(k)MOD(dp[now][j][k-1]+=dp[pre][j][k]*k%mod);
                    }
                }
        }
        printf("%lld",dp[now][0][0]*jie[cnt]%mod);
        return 0;
    }
    
  • 相关阅读:
    搭建单区域DNS服务器
    安装一个KVM服务器
    配置HTTPS网站服务器
    部署并测试动态WSGI站点
    java内置的四大函数式接口
    java自定义异常类
    java方法重写的规定
    spring跨重定向传递数据
    SpringEl表达式(转)
    Spring中的@conditional注解
  • 原文地址:https://www.cnblogs.com/ZH-comld/p/11002302.html
Copyright © 2011-2022 走看看