Problem p01550 (C++) — buggy submission, verdict: Memory Limit Exceeded

#include <algorithm>
#include <iostream>
#include <vector>
#define rep(i, n) for (int i = 0; i < n; i++)
using namespace std;
typedef long long ll;
int n, a[200];
ll func[201], perm[201][201], sump[201], p10[801], dp[4][2][201][801];
ll mod = 1e9 + 7;
int dig(int x) {
  if (x < 10)
    return 0;
  if (x < 100)
    return 1;
  if (x < 1000)
    return 2;
  return 3;
}
void add(ll &x, ll y) {
  x += y;
  if (x >= mod)
    x %= mod;
}
ll solve() {
  int cntd[4] = {}, sumd[4] = {};
  rep(i, n) cntd[dig(a[i])]++;
  rep(i, n) sumd[dig(a[i])] += a[i];
  rep(d, 4) {
    if (cntd[d] == 0)
      continue;
    vector<int> vc;
    rep(i, 4) rep(j, cntd[i]) {
      if (i == d && j == 0)
        continue;
      vc.push_back(i + 1);
    }
    dp[d][0][0][0] = 1;
    rep(i, vc.size()) {
      rep(j, vc.size() + 1) rep(k, 801) dp[d][1 - i % 2][j][k] = 0;
      rep(j, vc.size() + 1) {
        rep(k, 801) {
          if (dp[d][i % 2][j][k] == 0)
            continue;
          add(dp[d][1 - i % 2][j][k], dp[d][i % 2][j][k]);
          add(dp[d][1 - i % 2][j + 1][k + vc[i]], dp[d][i % 2][j][k]);
        }
      }
    }
  }
  ll ans = 0;
  rep(d, 4) {
    if (cntd[d] == 0)
      continue;
    rep(j, n) rep(k, 801)
        add(ans, sumd[d] * dp[d][1 - n % 2][j][k] % mod * func[j] % mod *
                     sump[n - 1 - j] % mod * p10[k]);
  }
  return ans;
}
int main() {
  func[0] = 1;
  rep(i, 200) func[i + 1] = func[i] * (i + 1) % mod;
  rep(i, 201) perm[i][0] = 1;
  rep(i, 201) rep(j, i) perm[i][j + 1] = perm[i][j] * (i - j) % mod;
  rep(i, 201) rep(j, i + 1) add(sump[i], perm[i][j]);
  p10[0] = 1;
  rep(i, 800) p10[i + 1] = p10[i] * 10 % mod;
  cin >> n;
  rep(i, n) cin >> a[i];
  ll ans = solve();
  sort(a, a + n);
  if (a[0] == 0) {
    swap(a[n - 1], a[0]);
    n--;
    rep(i, 4) rep(j, 2) rep(k, 201) rep(l, 801) dp[i][j][k][l] = 0;
    ll mn = solve();
    ans = (ans - mn + mod) % mod;
  }
  cout << ans << endl;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <vector>
#define rep(i, n) for (int i = 0; i < n; i++)
using namespace std;
typedef long long ll;
int n, a[200];
ll func[201], perm[201][201], sump[201], p10[801], dp[4][201][201][801];
ll mod = 1e9 + 7;
int dig(int x) {
  if (x < 10)
    return 0;
  if (x < 100)
    return 1;
  if (x < 1000)
    return 2;
  return 3;
}
void add(ll &x, ll y) {
  x += y;
  if (x >= mod)
    x %= mod;
}
ll solve() {
  int cntd[4] = {}, sumd[4] = {};
  rep(i, n) cntd[dig(a[i])]++;
  rep(i, n) sumd[dig(a[i])] += a[i];
  rep(d, 4) {
    if (cntd[d] == 0)
      continue;
    vector<int> vc;
    rep(i, 4) rep(j, cntd[i]) {
      if (i == d && j == 0)
        continue;
      vc.push_back(i + 1);
    }
    dp[d][0][0][0] = 1;
    rep(i, vc.size()) {
      rep(j, vc.size() + 1) {
        rep(k, 801) {
          if (dp[d][i][j][k] == 0)
            continue;
          add(dp[d][i + 1][j][k], dp[d][i][j][k]);
          add(dp[d][i + 1][j + 1][k + vc[i]], dp[d][i][j][k]);
        }
      }
    }
  }
  ll ans = 0;
  rep(d, 4) {
    if (cntd[d] == 0)
      continue;
    rep(j, n) rep(k, 801)
        add(ans, sumd[d] * dp[d][n - 1][j][k] % mod * func[j] % mod *
                     sump[n - 1 - j] % mod * p10[k]);
  }
  return ans;
}
int main() {
  func[0] = 1;
  rep(i, 200) func[i + 1] = func[i] * (i + 1) % mod;
  rep(i, 201) perm[i][0] = 1;
  rep(i, 201) rep(j, i) perm[i][j + 1] = perm[i][j] * (i - j) % mod;
  rep(i, 201) rep(j, i + 1) add(sump[i], perm[i][j]);
  p10[0] = 1;
  rep(i, 800) p10[i + 1] = p10[i] * 10 % mod;
  cin >> n;
  rep(i, n) cin >> a[i];
  ll ans = solve();
  sort(a, a + n);
  if (a[0] == 0) {
    swap(a[n - 1], a[0]);
    n--;
    rep(i, 4) rep(j, 201) rep(k, 201) rep(l, 801) dp[i][j][k][l] = 0;
    ll mn = solve();
    ans = (ans - mn + mod) % mod;
  }
  cout << ans;
}