# include <bits/stdc++.h>
# define N 110
int a[N];
bool f[N][100010];
int main() {
	int n,i,j,sum=0;
	scanf("%d",&n);
	for(i=1;i<=n;i++) scanf("%d",a+i), sum+=a[i];
	f[0][0]=true;
	for(i=0;i<n;i++) {
		for(j=0;j<=100000;j++) {
			if(f[i][j]) f[i+1][j+a[i+1]]=true, f[i+1][j]=true;
		}
	}
	int mid=(sum+1)/2;
	for(j=mid;!f[n][j];j++);
	printf("%d\n",j);
	return 0;
}
/*
    @uthor: Amit Kumar
    user -->GitHub: drviruses ; CodeChef: dr_virus_ ; Codeforces,AtCoder,Hackerearth,Hakerrank: dr_virus;
*/
#include <bits/stdc++.h>
#include <chrono>
using namespace std;
using namespace std::chrono;
//#include <boost/multiprecision/cpp_int.hpp>
//namespace mp = boost::multiprecision;
//#define ln mp::cpp_int;
#define int      long long
#define double   long double
#define uint     unsigned long long
#define all(vec) vec.begin(),vec.end()
#define endl "\n"
int google_itr = 1;
#define google(x) cout<<"Case #"<<x<<": "
#define pi 3.14159265358979323846264338327950L

vector<string> vec_splitter(string s) {
        s += ',';
        vector<string> res;
        while(!s.empty()) {
                res.push_back(s.substr(0, s.find(',')));
                s = s.substr(s.find(',') + 1);
        }
        return res;
}
void debug_out(
vector<string> __attribute__ ((unused)) args,
__attribute__ ((unused)) int idx, 
__attribute__ ((unused)) int LINE_NUM) { cerr << endl; } 
template <typename Head, typename... Tail>
void debug_out(vector<string> args, int idx, int LINE_NUM, Head H, Tail... T) {
        if(idx > 0) cerr << ", "; else cerr << "Line(" << LINE_NUM << ") ";
        stringstream ss; ss << H;
        cerr << args[idx] << " = " << ss.str();
        debug_out(args, idx + 1, LINE_NUM, T...);
}

#define XOX
#ifdef XOX
    #define deb(...) debug_out(vec_splitter(#__VA_ARGS__), 0, __LINE__, __VA_ARGS__)
#else
    #define deb(...) 42
#endif

const int mod = 1e9+7;
const int inf = 1e18;

unordered_set<string> seen;
int res = INT_MAX;
void minimumTimeRequired(vector<int>& jobs, int k, int start, vector<int>& assigned, int prefer) {
        // make a copy of the assignment, and use it to calculate the cache key and the workload of the worker with heaviest workload
        vector<int> a = assigned;
        sort(a.begin(), a.end());
        string key = "";
        int heaviest = 0;
        for (int num: a) {
            heaviest = max(heaviest, num);
            key += to_string(num) + "_";
        }
        // pruning trick 2
        if (heaviest > res) return;
        // pruning trick 1
        if(seen.find(key)!=seen.end()) return;
        seen.insert(key);
        if (start >=(int) jobs.size()) {
            // Found a possible assignment, check to see if it's better than what we have seen
            int sln = 0;
            for (int i=0; i<assigned.size(); i++) {
                sln = max(sln, assigned[i]);
            }
            res = min(res, sln);
            return;
        }  
        
        unordered_set<int> tried;
        for (auto j=0; j<assigned.size(); j++) {
            int i = (j + prefer) % k;
            if (tried.find(assigned[i]) != tried.end()) continue;
            tried.insert(assigned[i]);
            assigned[i] += jobs[start];            
            // pruning trick 3: force the next iteration to try to do assignments from the next worker
            minimumTimeRequired(jobs, k, start+1, assigned, prefer+1);
            assigned[i] -= jobs[start];
        }
    }

void virus(){
        int n, ans = 0;
        cin >> n;

        vector <int> arr(n);
        for(auto &i:arr) cin >> i;
        vector<int> assigned(2);
        sort(all(arr), greater <int>());
        minimumTimeRequired(arr, 2, 0, assigned, 0);
        cout << res << endl;
}


int32_t main(){
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    
  /*#ifndef ONLINE_JUDGE
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    #endif*/

    int t = 1;
    //cin >> t;
    while(t--){
           auto start = system_clock::now();
           virus();
           auto stop = system_clock::now();
           duration<double> duration = (stop - start);
           //cerr << "\nTime: "<< fixed << setprecision(10) << (double)duration.count() <<"sec"<< endl;
           //your code goes here
    }
    return 0;
}