Problem:
Score : 700 points

Problem Statement

You are given N integers A_1, A_2, ..., A_N.

Consider the sums of all non-empty subsequences of A. There are 2^N - 1 such sums, an odd number.

Let the list of these sums in non-decreasing order be S_1, S_2, ..., S_{2^N - 1}.

Find the median of this list, S_{2^{N-1}}.

Constraints

1 \leq N \leq 2000

1 \leq A_i \leq 2000

All input values are integers.

Input

Input is given from Standard Input in the following format:

N
A_1 A_2 ... A_N

Output

Print the median of the sorted list of the sums of all non-empty subsequences of A.

Sample Input 1

3
1 2 1

Sample Output 1

2

In this case, S = (1, 1, 2, 2, 3, 3, 4). Its median is S_4 = 2.

Sample Input 2

1
58

Sample Output 2

58

In this case, S = (58).

Solution in C# (Mono 4.6.2.0) (judge verdict: Time Limit Exceeded)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.IO;

namespace AtCoder
{
    class Program
    {
        private static string Read() { return Console.ReadLine(); }
        private static int ReadInt() { return int.Parse(Read()); }
        private static long ReadLong() { return long.Parse(Read()); }
        private static double ReadDouble() { return double.Parse(Read()); }
        private static int[] ReadInts() { return Array.ConvertAll(Read().Split(), int.Parse); }
        private static long[] ReadLongs() { return Array.ConvertAll(Read().Split(), long.Parse); }
        private static double[] ReadDoubles() { return Array.ConvertAll(Read().Split(), double.Parse); }

        private class BitSet
        {
            private readonly uint[] m_values;
            private BitSet(uint[] values) { m_values = values; }
            public BitSet(int length) { m_values = new uint[(length + 31) / 32]; }
            public bool this[int i]
            {
                get
                {
                    int p = i / 32;
                    int q = i % 32;
                    return (m_values[p] & (1U << q)) != 0;
                }
                set
                {
                    int p = i / 32;
                    int q = i % 32;
                    m_values[p] |= value ? (1U << q) : 0;
                }
            }
            public static BitSet operator |(BitSet lhs, BitSet rhs)
            {
                uint[] values = new uint[lhs.m_values.Length];
                for (int i = 0; i < values.Length; ++i) { values[i] = lhs.m_values[i] | rhs.m_values[i]; }
                return new BitSet(values);
            }
            public static BitSet operator <<(BitSet set, int shift)
            {
                uint[] values = new uint[set.m_values.Length];
                for (int i = 0; i < values.Length; ++i)
                {
                    int n1 = i - shift / 32;
                    int n2 = i - (shift + 31) / 32;
                    uint a = (n1 >= 0) ? set.m_values[n1] << (shift % 32) : 0;
                    uint b = (n2 >= 0) ? set.m_values[n2] >> (32 - shift % 32) : 0;
                    values[i] = a | b;
                }
                return new BitSet(values);
            }
            public int Search(int n)
            {
                for (int i = n / 32; i < m_values.Length; ++i)
                {
                    if (m_values[i] != 0)
                    {
                        for (int j = 0; j < 32; ++j)
                        {
                            if ((m_values[i] & (1U << j)) != 0 && (i > n / 32 || j >= n % 32))
                            {
                                return i * 32 + j;
                            }
                        }
                    }
                }
                return m_values.Length * 32;
            }
        }

        private static int Solve(int N, int[] A)
        {
            int sum = A.Sum();
            var set = new BitSet(sum + 1);
            set[0] = true;
            foreach (int a in A) { set |= (set << a); }
            return set.Search((sum + 1) / 2);
        }

        static void Main(string[] args)
        {
            int N = ReadInt();
            int[] A = ReadInts();
            Console.WriteLine(Solve(N, A));
        }
    }
}