Problem:
Score : 600 points

Problem Statement

You are given N integers. The i-th integer is a_i.
Find the number, modulo 998244353, of ways to paint each of the integers red, green or blue so that the following condition is satisfied:

Let R, G and B be the sums of the integers painted red, green and blue, respectively. There exists a triangle with positive area whose sides have lengths R, G and B.

Constraints

3 \leq N \leq 300

1 \leq a_i \leq 300(1\leq i\leq N)

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
a_1
:
a_N

Output

Print the number, modulo 998244353, of ways to paint each of the integers red, green or blue so that the condition is satisfied.

Sample Input 1

4
1
1
1
2

Sample Output 1

18

We can only paint the integers so that the lengths of the sides of the triangle will be 1, 2 and 2, and there are 18 such ways.

Sample Input 2

6
1
3
2
3
5
2

Sample Output 2

150

Sample Input 3

20
3
1
4
1
5
9
2
6
5
3
5
8
9
7
9
3
2
3
8
4

Sample Output 3

563038556

Solution in C++14 (GCC 5.4.1) (judge verdict: Runtime Error)

#include <iostream>
#include <vector>
#include <map>
#include <unordered_map>
#include <queue>
#include <set>
#include <algorithm>
#include <string>
#include <math.h>
#include <limits.h>
#include <stack>
#include <complex>
#include <stdlib.h>
#include <stdio.h>
#include <functional>
#include <cfloat>
#include <math.h>


#define fs first
#define sc second

using namespace std;

typedef long long ll;
typedef pair<ll, int> P;
ll mod = 998244353;

bool pp[2][101000];
int N;
int a[300];
vector<vector<ll>> dp(2, vector<ll>(1010000, 0));
unordered_map<int, int> mp;
vector<int> e;


int main(){
    cin >> N;
    int s = 0;
    for(int i = 0; i < N; i++){
        cin >> a[i];
        s += a[i];
    }

    pp[0][0] = true;
    for(int i = 0; i < N; i++){
        for(int j = 0; j < 101000; j++){
            pp[1][j] = pp[0][j];
            if(j - a[i] >= 0 && pp[0][j-a[i]]){
                pp[1][j] = true;
            }
        }
        for(int j = 0; j < 101000; j++){
            pp[0][j] = pp[1][j];
        }
    }

    for(int i = 0; i < 101000; i++){
        if(pp[0][i]){
            e.push_back(i);
        }
    }

    for(int i = 0; i < e.size(); i++){
        mp[e[i]] = i;
    }

    int n = e.size();
    dp[1][0] = 1;

    for(int i = 0; i < N; i++){
        int p = i % 2;
        int q = 1 - p;
        int x = a[i];
        for(int j = 0; j < n*n; j++){
            int red_w = e[j % n];
            int red_index = j % n;
            int blue_w = e[(j / n)];
            int blue_index = (j / n) * n;
            if(mp.find(x+red_w) != mp.end()){
                // 赤に加える
                int index = mp[red_w + x];
                ll add_red = (dp[p][blue_index + index] + dp[q][j]) % mod;
                dp[p][blue_index + index] = add_red;
            }

            if(mp.find(x+blue_w) != mp.end()){
                // 青に加える
                int index = mp[x + blue_w];
                ll add_blue = (dp[p][index * n + red_index] + dp[q][j]) % mod;
                dp[p][index * n + red_index] = add_blue;
            }
            // 緑に加える
            ll add_green = (dp[p][j] + dp[q][j]) % mod;
            dp[p][j] = add_green;
        }
        fill(dp[q].begin(), dp[q].end(), 0);
    }

    ll ret = 0;
    int p = (N-1) % 2;
    for(int i = 0; i < n*n; i++){
        int red = e[i % n];
        int blue = e[(i / n)];
        int green = s - red - blue;
        if(red + green > blue && red + blue > green && blue + green > red){
            ret = (ret + dp[p][i]) % mod;
        }
    }
    ret = (ret) % mod;

    cout << ret << endl;


    return 0;
}