#include <bits/stdc++.h>
#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
using namespace std;
using ll = long long;
using ld = long double;
const ll MOD = 1e9+7;
const ll INF=1LL<<60;
const string YYY="YES";
const string yyy="Yes";
const string NNN="NO";
const string nnn="No";
template<class T>void chmin(T& a,T b){
  if(a>b){
    a=b;
  }
}
template<class T>void chmax(T& a,T b){
  if(a>b){
    a=b;
  }
}
string rot13(string S){
  int a=S.size();
  for(int i=0;i<a;i++){
   if(S[i]=='a'){S[i]='n';continue;}
    if(S[i]=='b'){S[i]='o';continue;}
    if(S[i]=='c'){S[i]='p'; continue;}
    if(S[i]=='d'){S[i]='q'; continue;}
    if(S[i]=='e'){S[i]='r'; continue;}
    if(S[i]=='f'){S[i]='s'; continue;}
    if(S[i]=='g'){S[i]='t'; continue;}
    if(S[i]=='h'){S[i]='u'; continue;}
    if(S[i]=='i'){S[i]='v'; continue;}
    if(S[i]=='j'){S[i]='w'; continue;}
    if(S[i]=='k'){S[i]='x'; continue;}
    if(S[i]=='l'){S[i]='y'; continue;}
    if(S[i]=='m'){S[i]='z'; continue;}
    if(S[i]=='n'){S[i]='a'; continue;}
    if(S[i]=='o'){S[i]='b'; continue;}
    if(S[i]=='p'){S[i]='c'; continue;}
    if(S[i]=='q'){S[i]='d';continue;}
    if(S[i]=='r'){S[i]='e'; continue;}
    if(S[i]=='s'){S[i]='f'; continue;}
    if(S[i]=='t'){S[i]='g'; continue;}
    if(S[i]=='u'){S[i]='h'; continue;}
    if(S[i]=='v'){S[i]='i'; continue;}
    if(S[i]=='w'){S[i]='j'; continue;}
    if(S[i]=='x'){S[i]='k';continue;}
    if(S[i]=='y'){S[i]='l'; continue;}
    if(S[i]=='z'){S[i]='m'; continue;}
  }
  return S;
}
ll GD(ll num){//各桁の和
    ll digit=0;
    while(num!=0){
        digit+=num%10;
        num/=10;
    }
    return digit;
}
bool if_integer( ld x ){//整数判定
  return std::floor(x)==x;
}
bool if_prime(ll x){
  bool a=true;
  for(ll i=2;i*i<=x;i++){
   if(x%i==0){
    a=false;break; 
   }
  }
  if(x==1)a=false;
  return a;
}
ll gcd(ll x, ll y)//最大公約数
{
   if (x%y == 0)
   {
       return(y);
   }
   else
   {
       return(gcd(y, x%y));
   }
}

ll lcm(ll x, ll y)//最小公倍数
{
   return x / gcd(x, y)*y ;
}
inline ll mod(ll a, ll m) {
    return (a % m + m) % m;
}
ll modPow(ll a, ll n, ll p) {
  if (n == 0) return 1; // 0乗にも対応する場合
  if (n == 1) return a % p;
  if (n % 2 == 1) return (a * modPow(a, n - 1, p)) % p;
  ll t = modPow(a, n / 2, p);
  return (t * t) % p;
}
ll extGCD(ll a, ll b, ll &x, ll &y) {
    if (b == 0) {
        x = 1;
        y = 0;
        return a;
    }
    ll d = extGCD(b, a%b, y, x);
    y -= a/b * x;
    return d;
}
/////////////////////////
/////////////////////////
/////////////////////////
int main() {
  ios::sync_with_stdio(false);
  std::cin.tie(nullptr);
      ll N ;cin >> N ;
  ll sum=0;
    vector<int> a(N);
  ll y=0;
    for (int i = 0; i < N; i++) {
        cin >> a[i];
      sum+=a[i];
    }
  sort(a.begin(), a.end());
  for(int i=0;i<N-1;i++){
   y+=a[i]; 
  }
  if(y<a[N-1]){
   cout<<a[N-1];return 0; 
  }
  
  ll K=sum/2;
    // 二次元配列
    
      vector<vector<bool>> dp(N + 1, vector<bool>(K + 1, false));
    // 初期化
    for (int i = 0; i <= N; i++) {
        dp[i][0] = true;
    }
    // 更新
    for (int i = 0; i < N; i++) {
        for (int k = 0; k <= K; k++) {
            if (k - a[i] >= 0) dp[i + 1][k] = dp[i + 1][k] | dp[i][k - a[i]];
            dp[i + 1][k] = dp[i + 1][k] | dp[i][k];
        }
    }
      while(true){
      if (dp[N][K]) {
        cout << sum-K << endl;return 0;
    } else {
        K--;
    }
      }
      
      
    
   
}
# include <bits/stdc++.h>
 
using namespace std;
 
typedef long long ll;
typedef long double ld;
typedef complex<ld> cd;
 
typedef pair<int, int> pi;
typedef pair<ll,ll> pl;
typedef pair<ld,ld> pd;

#define FOR(i, begin, end) for(int i=(begin),i##_end_=(end);i<i##_end_;i++)
#define IFOR(i, begin, end) for(int i=(end)-1,i##_begin_=(begin);i>=i##_begin_;i--)
#define REP(i, n) FOR(i,0,n)
#define IREP(i, n) IFOR(i,0,n)
#define trav(a,x) for (auto& a : x)
#define uid(a, b) uniform_int_distribution<int>(a, b)(rng)
 
#define sz(x) (int)(x).size()
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define lb lower_bound
#define ub upper_bound
#define all(x) x.begin(), x.end()
#define ins insert
#define UNIQUE(x) sort(all(x)), x.erase(unique(all(x)), x.end())

typedef vector<int> vi;
typedef vector<ld> vd;
typedef vector<ll> vl;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<cd> vcd;
 
const int xn = 1e2 + 10;
const int sq = 320;
const int inf = 1e9 + 10;
const ll INF = 1e18 + 10;
const int mod = 1e9 + 7;//998244353;
const int base = 257;
const char nl = '\n';
bool ispow2(int i) { return i && (i & -i) == i; }

void solve() {

    int n; cin>>n;
    vector<int> t(n);
    FOR(i, 0, n) cin>>t[i]; 
    
    int s = 0;
    FOR(i, 0, n) {
        s += t[i];
    }
    
    vector<vector<bool> > dp(n+1, vector<bool>(s + 1, false));
    dp[0][0] = true;
    
    FOR(i, 0, n) {
        FOR(j, 0, s) {
            if(dp[i][j]) {
                dp[i + 1][j] = true;
                dp[i + 1][j + t[i]] = true;
            }
        }
    }
    
    int ans = s;
    
    FOR(i, 0, s) {
        if(dp[n][i]) {
            ans = min(ans, max(i, s - i));
        }
    }
    
    cout << ans;
    
    return;
}

 
int main(){
    ios::sync_with_stdio(0);cin.tie(0); cout.tie(0);
    int tc = 1; //cin>>tc;
    
    while(tc--) {
        solve();
    }
 
    return 0;
}