제출 #1109887

#제출 시각아이디문제언어결과실행 시간메모리
1109887vjudge1Magneti (COCI21_magneti)C++14
110 / 110
33 ms12872 KiB
#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

const int MAXN = 55, MAXL = 1e4 + 505, Mod = 1e9 + 7;
inline void UP(int &x, ll y) {x = (y + x) % Mod;}

int n, l, w[MAXN];
int ans;

int f[MAXN][MAXN][MAXL];

int fac[MAXL], ifc[MAXL], inv[MAXL];
void Fac() {
    fac[0] = ifc[0] = fac[1] = ifc[1] = inv[1] = 1;
    for (int i = 2; i < MAXL; ++i) {
        fac[i] = 1LL * fac[i - 1] * i % Mod;
        inv[i] = -1LL * inv[Mod % i] * (Mod / i) % Mod;
        ifc[i] = 1LL * ifc[i - 1] * inv[i] % Mod;
    }
    return ;
}
inline int C(int n, int m) {
    if (n < 0 || m < 0 || m > n) return 0;
    return 1LL * fac[n] * ifc[m] % Mod * ifc[n - m] % Mod;
}

int main() {
    cin.tie(nullptr)->sync_with_stdio(false);
    cin >> n >> l;
    for (int i = 1; i <= n; ++i) cin >> w[i];

    Fac();
    sort(w + 1, w + 1 + n);
    f[0][0][0] = 1;
    for (int i = 0; i < n; ++i)
        for (int j = 0; j <= i; ++j) {
            for (int k = 0; k < l; ++k) {
                int val = f[i][j][k];
                if (!val) continue;
                if (k + w[i + 1] <= l) UP(f[i + 1][j][k + w[i + 1]], 2LL * j * val);
                if (j >= 2 && k + 2 * w[i + 1] - 1 <= l) UP(f[i + 1][j - 1][k + 2 * w[i + 1] - 1], 1LL * (j - 1) * val);
                UP(f[i + 1][j + 1][k + 1], 1LL * (j + 1) * val);
            }
        }
    static int *g = f[n][1];
    for (int i = 0; i <= l; ++i)
        UP(ans, 1LL * g[i] * C(l - i + n, n));

    UP(ans, Mod);
    cout << ans;

    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...