제출 #1158249

#제출 시각아이디문제언어결과실행 시간메모리
1158249ace5Ruins 3 (JOI20_ruins3)C++20
0 / 100
5 ms10056 KiB
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int maxn = 605;
const int mod = int(1e9) + 7;

ll binpow(ll a,ll b)
{
    return (b == 0 ? 1 : (b%2 == 0 ? binpow((a*a)%mod,b/2) : (a*binpow(a,b-1))%mod));
}
ll del(ll a,ll b)
{
    return (a*binpow(b,mod-2))%mod;
}

ll cnk[2*maxn][2*maxn];

int dp[maxn][maxn];
int dp2[maxn][2*maxn];
int fact[2*maxn];
int a[maxn];


int ans =0;
vector<int> tk;

void rec(int pos,int n)
{
    if(pos == 2*n)
    {
        vector<int> vis(n+1);
        vis[0] = 1;
        vector<int> s;
        for(int j = 2*n-1;j >= 0;--j)
        {
           // cout << tk[j];
            for(int u = tk[j];u >= 0;u--)
            {
                if(!vis[u])
                {
                    s.push_back(j+1);
                    vis[u] = 1;
                    break;
                }
            }
        }
        int no = 0;
        for(int u = n-1;u >= 0;--u)
        {
            if(a[u] != s[n-u-1])
            {
                no = 1;
            }
        }
        ans += (!no);
        return ;
    }
    for(int j = 1;j <= n;++j)
    {
        int v = 0;
        for(int u = 0;u < tk.size();++u)
        {
            if(tk[u] == j)
                v++;

        }
        if(v < 2)
        {
            tk.push_back(j);
            rec(pos+1,n);
            tk.pop_back();
        }
    }
}

int solve_stupid(int n)
{
    tk.clear();
    ans = 0;
    rec(0,n);
    return ans;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    for(int i = 0;i < 2*maxn;++i)
    {
        for(int j = 0;j <= i;++j)
        {
            cnk[i][j] = (j == 0 ? 1 : (j == i ? 1 : (cnk[i-1][j] + cnk[i-1][j-1])%mod));
        }
    }
    fact[0] = 1;
    for(int i = 1;i < 2*maxn;++i)
    {
        fact[i] = (fact[i-1]*i)%mod;
    }
    int n;
    cin >> n;
    for(int i = 0;i < n;++i)
    {
        cin >> a[i];
    }
    for(int i = 0;i <= n;++i)
    {
        for(int j = 0;j <= 2*n;++j)
        {
            if(i == 0)
            {
                dp2[i][j] = 1;
            }
            else
            {
                if(j == 0 || j <= 2*(i-1))
                    dp2[i][j] = 0;
                else
                    dp2[i][j] = (dp2[i][j-1] + dp2[i-1][j-1])%mod;
            }
        }
    }
 //   cout << dp2[2][4] << ' ';
    if(a[n-1] != 2*n)
    {
        cout << 0;
        return 0;
    }
    dp[0][n] = 1;
    for(int i = 1;i <= n;++i)
    {
        for(int m = 0;m <= n;++m)
        {
            dp[i][m] = 0;
            for(int mn = m;mn <= n;++mn)
            {
                if(mn == m)
                {
                    int r = 2*n-a[i-1];
                    int re = n-i;
                    int cmn = r-re + mn;
                    int rem = 2*mn-cmn;
                    int pl = (a[i-1] - (i == 1 ? 0 : a[i-2]) - 1);
                    if(r >= re && rem >= pl)
                    {
                        dp[i][m] = (dp[i][m] + (dp[i-1][mn] * cnk[rem][pl])%mod * fact[pl])%mod;
                    }
                }
                else
                {
                    int r = 2*n-a[i-1];
                    int re = n-i;
                    int cmn = r-re + mn;
                    int rem = 2*mn-cmn;
                    int pl = (a[i-1] - (i == 1 ? 0 : a[i-2]) - 1);
                    if(r >= re && rem >= pl && re+1 >= mn)
                    {
                        ll w = ((((dp2[mn-m-1][2*(mn-m-1)] * cnk[re-m][mn-m-1])%mod) * (mn-m+1))%mod * fact[mn-m-1])%mod;
                        dp[i][m] = (dp[i][m] + ((dp[i-1][mn] * cnk[rem][pl])%mod * w)%mod * fact[pl])%mod;
                    }
                }
            }
            //cout << dp[i][m] << ' ';
        }
       // cout << "\n";
    }
    cout << del(dp[n][0],binpow(2,n));
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...