Submission #1124968

#TimeUsernameProblemLanguageResultExecution timeMemory
1124968pemguimnSkyscraper (JOI16_skyscraper)C++20
100 / 100
337 ms322248 KiB
#include <bits/stdc++.h>
#define int long long
using namespace std;

const int N = 1e2 + 5, S = 2e4 + 5, SHIFT = 1e3 + 5, MOD = 1e9 + 7;
int n, s, a[N];

namespace sub3{
    void solve(){
        int sum = 0;
        for(int i = 1; i <= n; i++) sum += a[i];
        int shift = -sum, lim;
        sum *= 2, lim = sum;
        vector<vector<vector<vector<int>>>> dp(3, vector<vector<vector<int>>>(n + 1, vector<vector<int>>(n + 1, vector<int>(lim + 1, 0))));
        dp[0][0][0][0 - shift] = 1;
        sum = 0;
        for(int i = 1; i <= n; i++){
            for(int cc = 1; cc <= i; cc++){
                for(int j = 0; j <= lim; j++){
                    if(j - 2 * a[i] >= 0){
                        // Create
                        for(int k = 0; k < 3; k++){
                            if(j + 2 * a[i] <= lim)
                                (dp[k][i][cc][j] += dp[k][i - 1][cc - 1][j + 2 * a[i]] * (cc - k)) %= MOD;
                            if(k >= 1 && j + a[i] <= lim)
                                (dp[k][i][cc][j] += dp[k - 1][i - 1][cc - 1][j + a[i]] * (2 - k + 1)) %= MOD;
                        }
                    }
                    if(cc){
                        // Append
                        for(int k = 0; k < 3; k++){
                            (dp[k][i][cc][j] += dp[k][i - 1][cc][j] * (2 * cc - k)) %= MOD;
                            if(k >= 1 && j >= a[i])
                                (dp[k][i][cc][j] += dp[k - 1][i - 1][cc][j - a[i]] * (2 - k + 1)) %= MOD;
                        }
                    }

                    // Merge
                    if(cc <= (n + 1) / 2){
                        for(int k = 0; k < 3; k++){
                            if(j >= 2 * a[i])
                                (dp[k][i][cc][j] += dp[k][i - 1][cc + 1][j - 2 * a[i]] * cc) %= MOD;
                        }
                    }
                }
            }
        }
        int ans = 0;
        for(int i = 0 - shift; i <= s - shift; i++){
            (ans += dp[2][n][1][i]) %= MOD;
        }
        cout << ans << '\n';
    }
}

namespace full{
    void solve(){
        vector<vector<vector<vector<int>>>> dp(3, vector<vector<vector<int>>>(n + 1, vector<vector<int>>(n + 1, vector<int>(s + 1, 0))));
        dp[0][0][0][0] = 1, a[n + 1] = a[n];
        for(int i = 1; i <= n; i++){
            for(int cc = 1; cc <= i; cc++){
                for(int j = 0; j <= s; j++){
                    for(int k = 0; k < 3; k++){
                        int inc = (a[i + 1] - a[i]) * (2 * cc - k);
                        if(j < inc) continue;
                        // Add
                        (dp[k][i][cc][j] += dp[k][i - 1][cc - 1][j - inc] * (cc - k)) %= MOD;

                        if(k)
                            (dp[k][i][cc][j] += dp[k - 1][i - 1][cc - 1][j - inc] * (2 - k + 1)) %= MOD;

                        // Append
                        (dp[k][i][cc][j] += dp[k][i - 1][cc][j - inc] * (2 * cc - k)) %= MOD;

                        if(k)
                            (dp[k][i][cc][j] += dp[k - 1][i - 1][cc][j - inc] * (2 - k + 1)) %= MOD;

                        // Merge
                        if(cc + 1 <= n)
                                (dp[k][i][cc][j] += dp[k][i - 1][cc + 1][j - inc] * cc) %= MOD;
                    }
                }
            }
        }
        int ans = 0;
        for(int i = 0; i <= s; i++){
            (ans += dp[2][n][1][i]) %= MOD;
        }
        cout << ans << '\n';
    }
}
signed main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);

    cin >> n >> s;
    if(n == 1){
        cout << 1 << '\n'; return 0;
    }
    for(int i = 1; i <= n; i++) cin >> a[i];

    sort(a + 1, a + n + 1);

//    if(n <= 40) return sub3::solve(), 0;
    full::solve();
    return 0;
}

#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...