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# (Mono 4.6.2.0) (judge verdict: Wrong Answer)

using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{
    static readonly Modulo modulo = new Modulo(998244353);
    static int N;
    static int[] a;

    public static void Main(string[] args)
    {
        N = Input.NextInt();
        a = new int[N];
        for (int i = 0; i < N; i++)
        {
            a[i] = Input.NextInt();
        }
        var total = a.Sum();
        var half = total / 2;
        var halfmod = total % 2;

        int n_all = modulo.Pow(3, N);


        int n_ng = 0;
        dp = new Dictionary<Param, int>();
        foreach (var redWeight in Enumerable.Range(half + halfmod, total - (half + halfmod) + 1))
        {
            var v = F(new Param(a.Length, redWeight, 0));
            n_ng = modulo.Plus(n_ng, v);
        }

        int n_ng2 = 0;
        dp = new Dictionary<Param, int>();
        foreach (var redWeight in Enumerable.Range(half + halfmod, total - (half + halfmod) + 1))
        {
            foreach (var greenWeight in Enumerable.Range(half + halfmod, total - (half + halfmod) + 1))
            {
                if (redWeight + greenWeight > total)
                    continue;
                var v = F(new Param(a.Length, redWeight, greenWeight));
                n_ng2 = modulo.Plus(n_ng2, v);
            }
        }

        var ans = modulo.Plus(modulo.Minus(n_all, 3 * n_ng), 3 * n_ng2);
        Console.WriteLine(ans);
    }

    static Dictionary<Param, int> dp;

    static int F(Param v)
    {
        if (dp.ContainsKey(v))
            return dp[v];

        int totalRed;
        if (v.Index == 0)
        {
            totalRed = v.TotalTheColor == 0 && v.TotalTheColor2 == 0 ? 1 : 0;
        }
        else
        {
            // no add
            var noAdd = F(new Param(v.Index - 1, v.TotalTheColor, v.TotalTheColor2)) * 2;
            totalRed = noAdd;

            // add 
            var newWeight = v.TotalTheColor - a[v.Index - 1];
            if (newWeight >= 0)
            {
                var yesAdd = F(new Param(v.Index - 1, newWeight, v.TotalTheColor2));
                modulo.PlusEq(ref totalRed, yesAdd);
            }
            var newWeight2 = v.TotalTheColor2 - a[v.Index - 1];
            if (newWeight2 >= 0)
            {
                var yesAdd = F(new Param(v.Index - 1, v.TotalTheColor, newWeight2));
                modulo.PlusEq(ref totalRed, yesAdd);
            }
        }

        return dp[v] = totalRed;
    }

    class Param
    {
        public Param(int index, int totalTheColor, int totalTheColor2)
        {
            Index = index;
            TotalTheColor = totalTheColor;
            TotalTheColor2 = totalTheColor2;
        }

        public int Index;
        public int TotalTheColor;
        public int TotalTheColor2;

        public override bool Equals(object obj)
        {
            if (obj == null || GetType() != obj.GetType())
            {
                return false;
            }

            var o = (Param)obj;

            return Index == o.Index && TotalTheColor == o.TotalTheColor && TotalTheColor2 == o.TotalTheColor2;
        }

        public override int GetHashCode()
        {
            return Index * 65537 + TotalTheColor + TotalTheColor2 * 257;
        }
    }
}

public static class Input
{
    private static Queue<string> q = new Queue<string>();
    private static void Confirm() { if (q.Count == 0) foreach (var s in Console.ReadLine().Split(' ')) q.Enqueue(s); }
    public static int NextInt() { Confirm(); return int.Parse(q.Dequeue()); }
    public static long NextLong() { Confirm(); return long.Parse(q.Dequeue()); }
    public static string NextString() { Confirm(); return q.Dequeue(); }
    public static double NextDouble() { Confirm(); return double.Parse(q.Dequeue()); }
    public static int[] LineInt() { return Console.ReadLine().Split(' ').Select(int.Parse).ToArray(); }
    public static long[] LineLong() { return Console.ReadLine().Split(' ').Select(long.Parse).ToArray(); }
    public static string[] LineString() { return Console.ReadLine().Split(' ').ToArray(); }
    public static double[] LineDouble() { return Console.ReadLine().Split(' ').Select(double.Parse).ToArray(); }
    public static void Lines(int N, out int[] a)
    {
        a = new int[N];
        for (int i = 0; i < N; i++)
        {
            var vals = LineInt();
            a[i] = vals[0];
        }
    }
    public static void Lines(int N, out int[] a, out int[] b)
    {
        a = new int[N];
        b = new int[N];
        for (int i = 0; i < N; i++)
        {
            var vals = LineInt();
            a[i] = vals[0];
            b[i] = vals[1];
        }
    }
    public static void Lines(int N, out int[] a, out int[] b, out int[] c)
    {
        a = new int[N];
        b = new int[N];
        c = new int[N];
        for (int i = 0; i < N; i++)
        {
            var vals = LineInt();
            a[i] = vals[0];
            b[i] = vals[1];
            c[i] = vals[2];
        }
    }
}

public class Modulo
{
    public int M { get; private set; }

    private static readonly List<int> m_facs = new List<int>() { 1, };

    public Modulo(int M = 1000000007)
    {
        this.M = M;
    }

    public int Mul(int a, int b)
    {
        return (int)(Math.BigMul(a, b) % M);
    }

    public int Fac(int n)
    {
        if (m_facs.Count <= n)
        {
            for (int i = m_facs.Count; i <= n; i++)
            {
                var facs_i = Mul(m_facs[i - 1], i);
                m_facs.Add(facs_i);
            }
        }
        return m_facs[n];
    }

    public int Pow(int a, int m)
    {
        switch (m)
        {
            case 0:
                return 1;
            case 1:
                return a;
            default:
                int p1 = Pow(a, m / 2);
                int p2 = Mul(p1, p1);
                return ((m % 2) == 0) ? p2 : Mul(p2, a);
        }
    }

    public int Div(int a, int b)
    {
        return Mul(a, Pow(b, M - 2));
    }

    public int Ncr(int n, int r)
    {
        if (n < r) { return 0; }
        if (n == r) { return 1; }
        int res = Fac(n);
        res = Div(res, Fac(r));
        res = Div(res, Fac(n - r));
        return res;
    }

    public int Plus(int a, int b)
    {
        PlusEq(ref a, b);
        return a;
    }

    public int Minus(int a, int b)
    {
        MinusEq(ref a, b);
        return a;
    }

    public void PlusEq(ref int a, int b)
    {
        a += b;
        a %= M;
    }

    public void MinusEq(ref int a, int b)
    {
        a -= b;
        if (a < 0)
            a += M;
        a %= M;
    }
}