Problem p03064 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <sstream>
#include <string>
#include <vector>

using namespace std;

long long MOD = 998244353L;

long long pow(int a, int n) {
  long long ret = 1;
  for (int i = 0; i < n; i++) {
    ret = (ret * a) % MOD;
  }
  return ret;
}

map<int, long long> memo;

long long doit(vector<int> &a, int n, int suma, int index, int s) {
  if (s * 2 > suma) {
    return 0;
  }
  if (index >= n) {
    return 3;
  }
  int key = s * n + index;
  if (memo.find(key) == memo.end()) {
    memo[key] = (doit(a, n, suma, index + 1, s + a[index]) * 2 +
                 doit(a, n, suma, index + 1, s)) %
                MOD;
  }
  return memo[key];
}

map<int, long long> memo2;

long long doit2(vector<int> &a, int n, int suma, int index, int s) {
  if (s * 2 > suma) {
    return 0;
  }
  if (index >= n) {
    return (s * 2 == suma) ? 3 : 0;
  }
  int key = s * n + index;
  if (memo2.find(key) == memo2.end()) {
    memo2[key] = (doit2(a, n, suma, index + 1, s + a[index]) +
                  doit2(a, n, suma, index + 1, s)) %
                 MOD;
  }
  return memo2[key];
}

int main() {
  int n;
  cin >> n;

  vector<int> a(n);
  int suma = 0;
  for (int i = 0; i < n; i++) {
    cin >> a[i];
    suma += a[i];
  }

  long long ret =
      (pow(3, n) - doit(a, n, suma, 0, 0) + doit2(a, n, suma, 0, 0) + MOD) %
      MOD;
  cout << ret << endl;

  return 0;
}


Fixed submission:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <sstream>
#include <string>
#include <vector>

using namespace std;

long long MOD = 998244353L;

long long pow(int a, int n) {
  long long ret = 1;
  for (int i = 0; i < n; i++) {
    ret = (ret * a) % MOD;
  }
  return ret;
}

map<int, long long> memo;

long long doit(vector<int> &a, int n, int suma, int index, int s) {
  if (s * 2 > suma) {
    return 0;
  }
  if (index >= n) {
    return 3;
  }
  int key = s * n + index;
  if (memo.find(key) == memo.end()) {
    memo[key] = (doit(a, n, suma, index + 1, s + a[index]) * 2 +
                 doit(a, n, suma, index + 1, s)) %
                MOD;
  }
  return memo[key];
}

map<int, long long> memo2;

long long doit2(vector<int> &a, int n, int suma, int index, int s) {
  if (s * 2 > suma) {
    return 0;
  }
  if (index >= n) {
    return (s * 2 == suma) ? 3 : 0;
  }
  int key = s * n + index;
  if (memo2.find(key) == memo2.end()) {
    memo2[key] = (doit2(a, n, suma, index + 1, s + a[index]) +
                  doit2(a, n, suma, index + 1, s)) %
                 MOD;
  }
  return memo2[key];
}

int main() {
  int n;
  cin >> n;

  vector<int> a(n);
  int suma = 0;
  for (int i = 0; i < n; i++) {
    cin >> a[i];
    suma += a[i];
  }

  vector<long long> dp1(suma + 1, 0);
  vector<long long> dp2(suma + 1, 0);
  dp1[0] = 3;
  dp2[0] = 3;
  for (int i = 0; i < n; i++) {
    vector<long long> next1(suma + 1, 0);
    vector<long long> next2(suma + 1, 0);
    for (int j = 0; j * 2 <= suma; j++) {
      next1[j] = (dp1[j] + (j >= a[i] ? dp1[j - a[i]] * 2 : 0)) % MOD;
      next2[j] = (dp2[j] + (j >= a[i] ? dp2[j - a[i]] : 0)) % MOD;
    }
    dp1 = next1;
    dp2 = next2;
  }
  long long ret = pow(3, n);
  for (int j = 0; j * 2 <= suma; j++) {
    ret = (ret - dp1[j] + MOD) % MOD;
  }
  if (suma % 2 == 0) {
    ret = (ret + dp2[suma / 2]) % MOD;
  }
  cout << ret << endl;

  return 0;
}