Problem:
双子の読書感想文
双子のアミとマミが通う学校では早くも夏休みに突入し，今年もおびただしい量の宿題が出された．
しかし，遊び盛りの2人は今日も宿題には一切手をつけずに外へ遊びに行こうとしていた．
このままでは夏休み最終日に泣きを見るのは明らかなので，保護者役のあなたは，心を鬼にして今日は読書感想文の宿題が終わるまで2人を家から出さないことにした．
準備の良いあなたは既に図書館から全ての課題図書を借りてある．
ただし，図書館の規則により各本は1冊ずつしか借りられていない．
さて，教育上の理由から2人には互いに協力することなく，それぞれ全ての本を読み，感想を書いてもらう事にした．
加えて，本の返却期限が近いため，まずはなるべく早くすべての本を読み終えるようにしてもらう事にした．
そして，あなたはその条件下でなるべく早く宿題が終わるような宿題の進め方を考えることにした．
ここで，本を読み終えた時間，宿題を終えた時間は，それぞれ双子の両方が作業を終えた時間で考える．
各本は1冊ずつしかないため，2人が同時刻に同じ本を読むことはできない．
加えて，大人の事情により，ある本を読み始めたらそれを中断する事はできず，ある本についての感想文を書き始めたらそれを中断することもできない．
当然ながら，読んでいない本について感想を書くこともできない．
なお，アミとマミは双子であるため，各本について読むのにかかる時間，感想文を書くのにかかる時間は2人で共通している．
例えば，3冊の本があり，それぞれ本を読むのにかかる時間，感想文を書くのにかかる時間が以下の通りであるとする．
本を読む時間
感想文を書く時間
本1
5
3
本2
1
2
本3
1
2
この場合は，図C-1のように宿題を進めると，時間10で全ての本を読み終え，時間15で宿題を終える事ができる．
図C-2の進め方では時間14で宿題を終えているが，本を読み終える時間が最短でないため，今回は採用できない．
また，図C-3のように2人が同時に同じ本を読んだり， 図C-4のように本を読むのを中断したり，読んでいない本の感想を書く事もできない．
図 C-1: 最短で宿題を終わらせる進め方の例
図 C-2: 本を読み終える時間が最短でない例
図 C-3: 2人が同時に同じ本を読んでしまっている例
図 C-4: 読んでいない本の感想を書いたり，作業を中断したりしている例
様々な大人の事情を考慮しつつ，遊びに行きたがっている双子のためになるべく早く宿題が終わるような進め方を考えてあげよう．
Input
入力は複数のデータセットから構成される．各データセットの形式は次の通りである．
N
r
1
w
1
r
2
w
2
...
r
N
w
N
Nは課題図書の数を表す整数であり，1以上1,000以下と仮定して良い．
続くN行は課題図書についての情報を表す．
各行はスペースで区切られた2つの整数を含み，r
i
(1 ≤ r
i
≤ 1,000) は i 番目の本を読むのにかかる時間，w
i
(1 ≤ w
i
≤ 1,000) は i 番目の本の感想文を書くのにかかる時間を表す．
N=0 は入力の終わりを示す．
これはデータセットには含めない．
Output
各データセットについて，2人が全ての本を読み終えるまでの時間を最小にしたときの，全ての感想文を書き終えるまでの最小の時間を1行に出力しなさい．
Sample Input
4
1 1
3 1
4 1
2 1
3
5 3
1 2
1 2
1
1000 1000
10
5 62
10 68
15 72
20 73
25 75
30 77
35 79
40 82
45 100
815 283
6
74 78
53 55
77 77
12 13
39 42
1 1
0
Output for Sample Input
14
15
3000
2013
522

Submitted solutions:

code_snippet: #include<bits/stdc++.h>
//#include <atcoder/all>
using namespace std;
//using namespace atcoder;

#define all(v) v.begin(),v.end()
using ll = long long;
using ull = unsigned long long;
using lll = __int128;
using vll=vector<ll>;
using vvll = vector<vector<ll>>;
using P = pair<ll,ll>;
using vp=vector<pair<ll, ll>>;
//using mint=modint1000000007;
//using mint=modint998244353;

const ll INF=1ll<<60;
ll mod10=1e9+7;
ll mod99=998244353;
const double PI = acos(-1);

#define rep(i,n) for (ll i=0;i<n;++i)
#define per(i,n) for(ll i=n-1;i>=0;--i)
#define rep2(i,a,n) for (ll i=a;i<n;++i)
#define per2(i,a,n) for (ll i=a;i>=n;--i)

template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return true; } return false; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return true; } return false; }

bool solve(){
	ll N;cin>>N;
	if(N==0) return 1;
	vll A(N),B(N);rep(i,N) cin>>A[i]>>B[i];
	vp AB(N);rep(i,N) AB[i]={A[i],B[i]};
	sort(all(AB),[&](P A,P B){
		if(A.first!=B.first) return A.first>B.first;
		else return A.second<B.second;
	});
	rep(i,N) A[i]=AB[i].first,B[i]=AB[i].second;
	ll ma=*max_element(all(A));
	ll sum=0;rep(i,N) sum+=A[i];sum-=ma;
	if(sum>=ma){
		ll ans=0;rep(i,N) ans+=A[i]+B[i];
		cout<<ans<<endl;
		return 0;
	}
	vvll dp(N+1,vll(1002));
	dp[0][0]=1;
	rep(i,N) rep(j,1001){
		if(i&&B[i]+j<=1000) dp[i+1][j+B[i]]|=dp[i][j];
		dp[i+1][j]|=dp[i][j];
	}
	ll ans=2*ma;rep(i,N) ans+=B[i];
	for(int i=ma-sum;i>=0;i--){
		if(dp[N][i]==1){
			ans-=i;
			break;
		}
	}
	cout << ans << endl;
	
	return 0;
}


int main(){
	cin.tie(0);
	ios::sync_with_stdio(false);
	while(!solve());
}
accuracy: 1
time_ms: 10
memory_kb: 10952
final_rank: 17

code_snippet: #line 2 "cp-library/src/cp-template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull  = unsigned long long;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
template < class T > bool chmin(T& a, T b) { if(a > b) { a = b; return true; } return false; }
template < class T > bool chmax(T& a, T b) { if(a < b) { a = b; return true; } return false; }
template < class T, class U > T ceil (T x, U y) { return (x > 0 ? (x + y - 1) / y :           x / y); }
template < class T, class U > T floor(T x, U y) { return (x > 0 ?           x / y : (x - y + 1) / y); }
int popcnt(i32 x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(i64 x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }

#line 2 "cp-library/src/utility/rep_itr.hpp"
template < class T > struct itr_rep {
    T i, d;
    constexpr itr_rep(const T i) noexcept : i(i), d(1) {}
    constexpr itr_rep(const T i, const T d) noexcept : i(i), d(d) {}
    void operator++() noexcept { i += d; }
    constexpr int operator*() const noexcept { return i; }
    constexpr bool operator!=(const itr_rep x) const noexcept { return d > 0 ? i < x.i : i > x.i; }
};

template < class T > struct rep {
    const itr_rep< T > s, t;
    constexpr rep(const T t) noexcept : s(0), t(t) {}
    constexpr rep(const T s, const T t) noexcept : s(s), t(t) {}
    constexpr rep(const T s, const T t, const T d) noexcept : s(s, d), t(t, d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};

template < class T > struct revrep {
    const itr_rep < T > s, t;
    constexpr revrep(const T t) noexcept : s(t - 1, -1), t(-1, -1) {}
    constexpr revrep(const T s, const T t) noexcept : s(t - 1, -1), t(s - 1, -1) {}
    constexpr revrep(const T s, const T t, const T d) noexcept : s(t - 1, -d), t(s - 1, -d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};
#line 3 "cp-library/src/utility/io.hpp"

/* 128bit integer */
istream& operator>>(istream& is, i128& x) {
    std::string s; is >> s;
    int pm = (s[0] == '-');
    x = 0;
    for(int i : rep(pm, int(s.size()))) x = x * 10 + (s[i] - '0');
    if(pm) x *= -1;
    return is;
}
ostream& operator<<(ostream& os, const i128& x) {
    if(x == 0) return os << '0';
    i128 y = x;
    if(y < 0) { os << '-'; y *= -1; }
    std::vector<int> ny;
    while(y > 0) { ny.push_back(y % 10); y /= 10; }
    for(int i : revrep(ny.size())) os << ny[i];
    return os;
}

template < class S, class T > istream& operator>>(istream& is,       std::pair< S, T >& x) { is >> x.first        >> x.second; return is; }
template < class S, class T > ostream& operator<<(ostream& os, const std::pair< S, T >& x) { os << x.first << " " << x.second; return os; }

namespace scanner {
    struct sca {
        template < class T > operator T() {
            T s; std::cin >> s; return s;
        }
    };
    struct vec {
        int n;
        vec(int n) : n(n) {}
        template < class T > operator std::vector< T >() {
            std::vector< T > v(n);
            for(T& x : v) std::cin >> x;
            return v;
        }
    };
    struct mat {
        int h, w;
        mat(int h, int w) : h(h), w(w) {}
        template < class T > operator std::vector< std::vector< T > >() {
            std::vector m(h, std::vector< T >(w));
            for(std::vector< T >& v : m) for(T& x : v) std::cin >> x;
            return m;
        }
    };
    struct speedup {
        speedup() {
            std::cin.tie(0);
            std::ios::sync_with_stdio(0);
        }
    } speedup_instance;
}
scanner::sca in() { return scanner::sca(); }
scanner::vec in(int n) { return scanner::vec(n); }
scanner::mat in(int h, int w) { return scanner::mat(h, w); }

namespace printer {
    void precision(int d) { std::cout << std::fixed << std::setprecision(d); }
    void flush() { std::cout.flush(); }
}

template < class T >
ostream& operator<<(ostream& os, const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) { os << a[i]; if(i != n - 1) os << ' '; }
    return os;
}

int print() { std::cout << '\n'; return 0; }
template < class head, class... tail > int print(head&& h, tail&&... t) {
    std::cout << h; if(sizeof...(tail)) std::cout << ' ';
    return print(std::forward<tail>(t)...);
}
template < class T > int print_n(const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) std::cout << a[i] << "\n";
    return 0;
}


#line 2 "cp-library/src/utility/key_val.hpp"

template < class K, class V >
struct key_val {
    K key; V val;
    key_val() {}
    key_val(K key, V val) : key(key), val(val) {}
    template < std::size_t Index >
    std::tuple_element_t< Index, key_val >& get() {
        if constexpr (Index == 0) return key;
        if constexpr (Index == 1) return val;
    }
};

namespace std {

template < class K, class V > struct tuple_size < key_val< K, V > > : integral_constant< size_t, 2 > {};
template < class K, class V > struct tuple_element < 0, key_val< K, V > > { using type = K; };
template < class K, class V > struct tuple_element < 1, key_val< K, V > > { using type = V; };

}
#line 2 "cp-library/src/utility/vec_op.hpp"
template < class T > key_val< int, T > max_of(const vector< T >& a) {
    int i = std::max_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class T > key_val< int, T > min_of(const vector< T >& a) {
    int i = std::min_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class S, class T > S sum_of(const vector< T >& a) {
    S sum = 0;
    for(const T x : a) sum += x;
    return sum;
}
template < class S, class T > vector< S > freq_of(const vector< T >& a, T L, T R) {
    vector< S > res(R - L, S(0));
    for(const T x : a) res[x - L] += 1;
    return res;
}
template < class S, class T > struct prefix_sum {
    vector< S > s;
    prefix_sum(const vector< T >& a) : s(a) {
        s.insert(s.begin(), S(0));
        for(int i : rep(a.size())) s[i + 1] += s[i];
    }
    // [L, R)
    S sum(int L, int R) { return s[R] - s[L]; }
};
#line 3 "cp-library/src/utility/heap.hpp"

template < class T > using heap_min = std::priority_queue< T, std::vector< T >, std::greater< T > >;
template < class T > using heap_max = std::priority_queue< T, std::vector< T >, std::less< T > >;

#line 27 "cp-library/src/cp-template.hpp"

#line 1 "cp-library/src/algorithm/bin_search.hpp"
template < class T, class F >
T bin_search(T ok, T ng, F f) {
    while(abs(ng - ok) > 1) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}

template < class T, class F >
T bin_search_real(T ok, T ng, F f, int step = 80) {
    while(step--) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}
#line 2 "cp-library/src/algorithm/argsort.hpp"

template < class T > std::vector< int > argsort(const std::vector< T > &a) {
    std::vector< int > ids((int)a.size());
    std::iota(ids.begin(), ids.end(), 0);
    std::sort(ids.begin(), ids.end(), [&](int i, int j) {
        return a[i] < a[j] || (a[i] == a[j] && i < j);
    });
    return ids;
}
#line 1 "macro.hpp"
namespace macro {

using size_type = int;
template < class container > void  sort(container& a) { std::sort(std:: begin(a), std:: end(a)); }
template < class container > void rsort(container& a) { std::sort(std::rbegin(a), std::rend(a)); }
template < class container > void reverse(container& a) { std::reverse(std::begin(a), std::end(a)); }
template < class container > void unique(container& a) {
    std::sort(std::begin(a), std::end(a));
    a.erase(std::unique(std::begin(a), std::end(a)), std::end(a));
}
template < class container > container  sorted(const container& a) { container b = a;  sort(b); return std::move(b); }
template < class container > container rsorted(const container& a) { container b = a; rsort(b); return std::move(b); }
template < class container, class compare > void sort(container& a, const compare& cmp) { std::sort(std::begin(a), std::end(a), cmp); }
template < class container, class compare > container sorted(const container& a, const compare& cmp) { container b = a; sort(b, cmp); return std::move(b); }
template < class container, class value > size_type lower_bound(const container& a, const value& x) { return std::lower_bound(std::begin(a), std::end(a), x) - std::begin(a); }
template < class container, class value > size_type upper_bound(const container& a, const value& x) { return std::upper_bound(std::begin(a), std::end(a), x) - std::begin(a); }

const std::vector<std::pair<size_type, size_type>> dir4 = { {+1,  0}, {-1,  0}, { 0, +1}, { 0, -1} };
const std::vector<std::pair<size_type, size_type>> dir8 = { {-1, -1}, {-1,  0}, {-1, +1}, { 0, -1}, { 0, +1}, {+1, -1}, {+1,  0}, {+1, +1} };

#ifdef _DEBUG
#define debug(x) std::cout << "[" << __LINE__ << "] " << #x << ": " << x << std::endl
#else
#define debug(x)
#endif

template < class container > void concat(container& a, const container& b) {
    a.insert(std::end(a), std::begin(b), std::end(b));
}
std::vector<size_type> iota(const size_type n) {
    std::vector<size_type> I(n);
    std::iota(std::begin(I), std::end(I), 0);
    return I;
}
template < class container > std::vector<size_type> sort_idx(const container& a) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return a[i] < a[j] or (a[i] == a[j] and i < j); });
    return I;
}
template < class container, class compare > std::vector<size_type> sort_idx(const container& a, const compare& cmp) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return cmp(a[i], a[j]) or (a[i] == a[j] and i < j); });
    return std::move(I);
}

struct grid {
    using size_type = int;
    size_type H, W;
    grid(const size_type H, const size_type W) : H(H), W(W) {}
    bool contains(const size_type i, const size_type j) {
        return 0 <= i and i < H and 0 <= j and j < W;
    }
};

using f64 = long double;

} // namespace macro

using namespace macro;
#line 3 "A.cpp"

int solve(int n) {
    vector<pair<int,int>> rw(n);
    for(auto &[r, w] : rw) r = in(), w = in();
    rsort(rw);
    int rsum = 0, rmax = rw[0].first;
    for(int i : rep(n)) if(i) rsum += rw[i].first;
    if(rmax <= rsum) {
        int ans = 0;
        for(int i : rep(n)) ans += rw[i].second;
        return (rmax + rsum) + ans;
    } else {
        bitset<1'000'001> dp;
        dp[0] = 1;
        for(int i : rep(n)) if(i) dp |= dp << rw[i].second;

        int wsum = 0;
        for(int i : rep(n)) wsum += rw[i].second;

        int ans = 1e9;
        for(int w = 0; w <= 1'000'000; w++) {
            if(dp[w] and w <= rmax - rsum) {
                chmin(ans, rmax + rmax + wsum - w);
            }
        }
        return ans;
    }
}

int main() {
    while(true) {
        int n = in();
        if(n == 0) return 0;
        print(solve(n));
    }
}
accuracy: 1
time_ms: 120
memory_kb: 3800
final_rank: 19

code_snippet: #include <bits/stdc++.h>

using namespace std;
using ll = long long;
using ld = long double;

template<class T>
bool chmin(T &a, const T &b) {if (a > b) {a = b; return 1;} return 0;}

template<class T>
bool chmax(T &a, const T &b) {if (a < b) {a = b; return 1;} return 0;}

bool is_end = false;

bool dp[2][1010];

void init()
{
    for (int i = 0; i < 2; ++i)
    {
        for (int j = 0; j < 1010; ++j)
        {
            dp[i][j] = false;
        }
    }
    return;
}

void calc()
{
    ll N; cin >> N;
    
    if (N == 0)
    {
        is_end = true;
        return;
    }
    
    vector<ll> R(N), W(N);
    for (int i = 0; i < N; ++i)
    {
        cin >> R[i] >> W[i];
    }
    
    vector<ll> Rcopy = R;
    sort(Rcopy.begin(), Rcopy.end());
    reverse(Rcopy.begin(), Rcopy.end());
    ll r_sum = accumulate(Rcopy.begin(), Rcopy.end(), 0LL);
    ll is_over = false;
    if (r_sum < Rcopy[0] * 2) {is_over = true;}
    
    if (!is_over)
    {
        ll res = accumulate(W.begin(), W.end(), 0LL);
        res += r_sum;
        cout << res << endl;
        return;
    }
    else
    {
        ll tot = accumulate(W.begin(), W.end(), 0LL) + r_sum;
        ll hima = Rcopy[0] * 2 - r_sum;
        // hima の間にどれだけ感想文を書けるか
        vector<ll> Wcopy;
        for (int i = 0; i < N; ++i)
        {
            if (R[i] == Rcopy[0]) {continue;}
            Wcopy.emplace_back(W[i]);
        }
        
        init();
        
        dp[0][0] = true;
        for (int i = 0; i < N-1; ++i)
        {   
            for (int t = 0; t < 1010; ++t)
            {
                ll w = Wcopy[i];
                
                if (dp[0][t])
                {
                    dp[1][t] = true;
                    if (t + w < 1010) {dp[1][t+w] = true;}                    
                }
            }
            
            for (int t = 0; t < 1010; ++t)
            {
                dp[0][t] = dp[1][t];
                dp[1][t] = false;
            }
            
        }
        
        ll vacant = hima;
        for (int t = 0; t <= hima; ++t)
        {
            if (dp[0][t]) {chmin(vacant, hima - t);}
        }
        
        ll res = tot + vacant;
        cout << res << endl;
        return;
        
        
    }
    
    
    return;
}

int main() {
    
    while (!is_end)
    {
        calc();
    }
    
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3484
final_rank: 5

code_snippet: #define rep(i, n) for(int i=0; i<(n); ++i)
#define rrep(i, n) for(int i=(n-1); i>=0; --i)
#define rep2(i, s, n) for(int i=s; i<(n); ++i)
#define ALL(v) (v).begin(), (v).end()
#define memr(dp, val) memset(dp, val, sizeof(dp))
#define fi first
#define se second
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
#include <bits/stdc++.h>
using namespace std;
template<typename T>
using min_priority_queue = priority_queue<T, vector<T>, greater<T> >;
typedef long long ll;
const int INTINF = INT_MAX >> 1;
static const ll LLINF = (LLONG_MAX >> 1);

int N;
int r[10001], w[10001];
int dp[1001][1001];

bool input(){

	cin >> N;
	if(!N) return false;
	rep(i, N) cin >> r[i] >> w[i];

	return true;
}

int main(){
    std::cout << std::fixed << std::setprecision(15);

	while(input()){
		int ans = 0;
		vector<pair<int, int> > rw;
		rep(i, N){
			rw.push_back({r[i], w[i]});
		}
		sort(ALL(rw), [](auto a, auto b){
			return a.fi > b.fi;
		});
		int sum = 0;
		rep(i, N){
			sum += rw[i].fi;
		}
		int wsum = 0;
		rep(i, N){
			wsum += rw[i].se;
		}
		if(rw[0].fi > sum - rw[0].fi){
			rep(i, 1001) rep(j, 1001) dp[i][j] = INTINF;
			dp[1][0] = 0;
			rep2(i, 1, N){
				rep(j, 1001){
					if(dp[i][j] == INTINF) continue;
					dp[i + 1][j] = 0;
					if(j + rw[i].se > 1000) continue;
					dp[i + 1][j + rw[i].se] = 0;
				}
			}
			int diff = rw[0].fi - (sum - rw[0].fi); // A - B
			int ma = 0;
			rep(i, diff+1){
				if(dp[N][i] == 0) chmax(ma, i);
			}
			ans = 2 * rw[0].fi + wsum - ma;
		}
		else{
			ans = sum + wsum;
		}

		cout << ans << endl;
	}
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 7292
final_rank: 16

code_snippet: #include<cstdio>
#include<bitset>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> P;

ll n, r[1000], w[1000];
P p[1000];

int main() {
  while (scanf("%lld", &n), n) {
    ll rsum = 0, wsum = 0;
    for (ll i = 0; i < n; i++) {
      scanf("%lld%lld", &r[i], &w[i]);
      p[i] = P(r[i], w[i]);
      rsum += r[i];
      wsum += w[i];
    }
    sort(p, p+n, greater<P>());
    for (ll i = 0; i < n; i++) r[i] = p[i].first, w[i] = p[i].second;
    if (r[0] * 2 <= rsum) {
      printf("%lld\n", rsum + wsum);
    } else {
      ll can_write = r[0] * 2 - rsum;
      bitset<1000000> dp;
      dp[0] = 1;
      for (ll i = 1; i < n; i++) dp |= dp << w[i];
      for (ll i = can_write; i >= 0; i--) if (dp[i]) {
        printf("%lld\n", rsum + wsum + can_write - i);
        break;
      }
    }
  }
}
accuracy: 1
time_ms: 100
memory_kb: 3380
final_rank: 18

code_snippet: #include<iostream>
#include<iomanip>
#include<cassert>
#include<math.h>
#include<complex>
#include<algorithm>
#include<utility>
#include<queue>
#include<string.h>
#include<string>
#include<set>
#include<map>
#include<unordered_map>
#include<functional>
#include<vector>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> LL;
const ll INF=2e18;
const ll MOD=1e9+7;
const double EPS=1e-9;
void ChMin(ll& x, ll y){
    x=min(x,y);
}
void ChMax(ll& x, ll y){
    x=max(x,y);
}

ll N;
ll r[1010],w[1010];
int main(){
  while( cin>>N, N!=0){
    for(ll i=0;i<N;i++){
      cin>>r[i]>>w[i];
    }
    ll rMax=0, rMaxIndex=0;
    ll rSum=0, wSum=0;
    for(ll i=0;i<N;i++){
      if(rMax<r[i]){
        rMax=r[i];
        rMaxIndex=i;
      }
      rSum += r[i];
      wSum += w[i];
    }
    if(rMax*2<=rSum){
      cout<<rSum+wSum<<endl;
      continue;
    }
    vector<vector<bool>> dp(N+1,vector<bool>(rMax+1,false));
    dp[0][0] = true;
    for(ll i=0;i<N;i++){
      for(ll j=0;j<=rMax;j++){
        dp[i+1][j] = dp[i+1][j] | dp[i][j];
        if(i==rMaxIndex)continue;
        if(j+w[i]<=rMax)
          dp[i+1][j+w[i]] = dp[i+1][j+w[i]] | dp[i][j];
      }
    }
    ll ans = rMax*2+wSum;
    for(ll i=rMax*2-rSum;i>=0;i--){
      if(dp[N][i]){
        cout<<ans-i<<endl;
        break;
      }
    }
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3512
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;

using P = pair<int, int>;

void solve()
{
	//1 <= n <= 1000
	int n;
	cin >> n;
	if (n == 0) exit(0);
	vector<P> kadai(n);
	int r, w;
	for (int i = 0; i < n; ++i)
		cin >> r >> w, kadai[i] = {r, w};
	sort(kadai.begin(), kadai.end());
	if (n == 1)
	{
		cout << kadai[0].first * 2 + kadai[0].second << endl;
		return ;
	}
	long long read_all = 0;
	for (int i = 0; i < n - 1; ++i) read_all += kadai[i].first;
	if (read_all < kadai.back().first)
	{
		long long diff = kadai.back().first - read_all;
		vector<vector<bool>> dp(n, vector<bool>(1001, false));
		dp[0][0] = true;
		for (int i = 0; i < n - 1; ++i)
		{
			for (int j = 0; j < 1001; ++j)
			{
				dp[i + 1][j] = dp[i + 1][j] | dp[i][j];
				if (dp[i][j] == false) continue ;
				if (j + kadai[i].second > 1000) continue ;
				dp[i + 1][j + kadai[i].second] = true;
			}
		}
		diff = min((long long)1000, diff);
		while (dp[n - 1][diff] == false) --diff;
		long long ans = 0;
		for (int i = 0; i < n; ++i) ans += kadai[i].second;
		ans = kadai.back().first * 2 + ans - diff;
		cout << ans << endl;
	}
	else
	{
		long long ans = 0;
		for (int i = 0; i < n; ++i)
			ans += kadai[i].first + kadai[i].second;
		cout << ans << endl;
	}
}

int	main(void)
{
	while (1) solve();
	return (0);
}
accuracy: 1
time_ms: 10
memory_kb: 3576
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define REP(i,n) for(int i=0;i<(n);i++)
#define ALL(v) v.begin(),v.end()

typedef pair<int,int> P;

signed main(){
  int n;
  while(cin>>n,n){
    vector<P> v(n);
    REP(i,n){
      int r,w;cin>>r>>w;
      v[i]=P(r,w);
    }
    sort(v.rbegin(),v.rend());
    //aにはv[0]から読ませ始め、bにはv[1]から読ませ始める
    //aがbに追いつくことは無く、bがaに追いつく可能性があるのはv[1]~v[n-1]がv[0]より短い時だけ
    //bがaに追いつかない時は感想の総和を足して終わり
    //bがaに追いつく時は？bがv[0]-(sum:v[1]~v[n-1])が一番小さくなるように感想を書いて 余った時間を感想の総和に足せばOK
    int sumr=0,sumw=0;
    REP(i,n)sumr+=v[i].first,sumw+=v[i].second;
    if(sumr-v[0].first>=v[0].first)cout<<sumr+sumw<<endl;
    else{
      int T=v[0].first-(sumr-v[0].first);
      bitset<123456> bs(1);
      REP(i,n)if(i)bs|=bs<<v[i].second;
      int ans=0;
      REP(i,T+1)if(bs[i])ans=i;
      cout<<sumr+sumw+T-ans<<endl;
    }
  }
}
accuracy: 1
time_ms: 20
memory_kb: 3204
final_rank: 12

code_snippet: #include <bits/stdc++.h>
//#include <atcoder/all>
//using namespace atcoder;
const double pi = 3.141592653589793238462643383279;
using namespace std;
//typedef
//------------------------------------------
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef pair<long long, long long> PLL;
typedef pair<int, PII> TIII;
typedef long long LL;
typedef unsigned long long ULL;
typedef vector<LL> VLL;
typedef vector<VLL> VVLL;

//container util
//------------------------------------------
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define MP make_pair
#define SZ(a) int((a).size())
#define SQ(a) ((a) * (a))
#define EACH(i, c) for (typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define EXIST(s, e) ((s).find(e) != (s).end())
#define SORT(c) sort((c).begin(), (c).end())

//repetition
//------------------------------------------
#define FOR(i, s, n) for (int i = s; i < (int)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define MOD 1000000007

#define rep(i, a, b) for (int i = a; i < (b); ++i)
#define trav(a, x) for (auto &a : x)
#define all(x) x.begin(), x.end()
#define sz(x) (int)(x).size()

typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;

#define chmin(x, y) x = min(x, y)
#define chmax(x, y) x = max(x, y)
const double EPS = 1e-8, PI = acos(-1);
//ここから編集    
typedef string::const_iterator State;

struct UnionFind{
  vector<int> par;
  vector<int> siz;

  UnionFind(int sz_): par(sz_), siz(sz_) {
    for(int i=0; i<sz_; ++i) par[i] = i, siz[i] = 1;
  }

  void init(int sz_){
    par.resize(sz_);
    siz.resize(sz_);
    for(int i=0; i<sz_; ++i) par[i] = i, siz[i] = 1;
  }

  int root(int x){
    if(x == par[x]) return x;
    return par[x] = root(par[x]);
  }

  bool merge(int x, int y){
    x = root(x), y = root(y);
    if(x == y) return false;
    if(siz[x] < siz[y]) swap(x, y);
    siz[x] += siz[y];
    par[y] = x;
    return true;
  }

  bool issame(int x, int y){
    return root(x) == root(y);
  }

  int size(int x){
    return siz[root(x)];
  }
};

int main()
{
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(6);

    ll n;
    while(cin >> n, n)
    {
        vector<int> r(n), w(n);
        int t = 0;
        int mx = 0;
        int idx = 0;
        REP(i,n) {
            cin >> r[i] >> w[i];
            if(mx < r[i]){
                idx = i;
                mx = r[i];
            }
            t += r[i];
        }
        if(2*mx > t){
            vector<vector<int>> dp(n+1, vector<int>(1010, -1));
            dp[0][0] = 0;
            for(int i=0; i<n; i++){
                if(i == idx){
                    for(int j=0; j<=1000; j++){
                        dp[i+1][j] = max(dp[i+1][j], dp[i][j]);
                    }
                }else{
                    for(int j=0; j<=1000; j++){
                        if(dp[i][j] == -1) continue;
                        int tt = j +  r[i] + w[i];
                        if(tt <= mx){
                            dp[i+1][tt] = max(dp[i+1][tt], dp[i][j] + 1);
                        }
                        tt = j + r[i];
                        if(tt <= mx){
                            dp[i+1][tt] = max(dp[i+1][tt], dp[i][j] + 1);
                        }
                        dp[i+1][j] = max(dp[i+1][j], dp[i][j]);
                    }
                }

            }                
            int tmp = 0;
            for(int i=0; i<=1000; i++){
                tmp = max(tmp, dp[n][i]);
            }
            int aba = 0;
            for(int i=0; i<=1000; i++){
                if(dp[n][i] == tmp){
                    aba = i;
                }
            }
            cout << mx-aba + accumulate(all(r), 0) + accumulate(all(w), 0) << endl;
        }else{
            cout << accumulate(all(r), 0) + accumulate(all(w), 0) << endl;
        }
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 6748
final_rank: 13

code_snippet: #include <bits/stdc++.h>
using namespace std;

bool chmax(int &a, int b){
    if(a < b){
        a = b;
        return true;
    }
    return false;
}

bool solve(){
    int n;
    cin >> n;
    if(n == 0) return false;
    int rmax = 0, idx = 0, rsum = 0, wsum = 0;
    vector<int> r(n), w(n);
    for(int i=0;i<n;i++){
        cin >> r[i] >> w[i];
        rsum += r[i];
        wsum += w[i];
        if(chmax(rmax,r[i])){
            idx = i;
        }
    }
    if(rmax*2 > rsum){
        swap(r[idx],r[n-1]);
        swap(w[idx],w[n-1]);
        vector<vector<int> > dp(n, vector<int>(rmax+1,0));
        dp[0][0] = 1;
        for(int i=0;i<n-1;i++){
            for(int j=0;j<rmax;j++){
                if(dp[i][j] == 0) continue;
                if(j+r[i]<=rmax) dp[i+1][j+r[i]] |= dp[i][j];
                if(j+r[i]+w[i]<=rmax) dp[i+1][j+r[i]+w[i]] |= dp[i][j];
            }
        }
        int k = 0;
        for(int i=0;i<=rmax;i++){
            if(dp[n-1][i]) k = i;
        }
        cout << rsum + wsum + (rmax-k) << endl;
    }else{
        cout << rsum + wsum << endl;
    }
    return true;
}

int main(){
    while(solve());
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 6808
final_rank: 14

code_snippet: #include<bits/stdc++.h> 
using namespace std;
typedef long long ll;
template<typename T1,typename T2> bool chmin(T1 &a,T2 b){if(a<=b)return 0; a=b; return 1;}
template<typename T1,typename T2> bool chmax(T1 &a,T2 b){if(a>b)return 0; a=b; return 1;}
#define bitUP(x,a) ((x>>a)&1)
int dx[4]={0,1,0,-1}, dy[4]={1,0,-1,0};
long double eps = 1e-18;
long double pi = acos(-1);



signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout << fixed << setprecision(20);

    bool dp[1100][1100];
    while(1){
        int N;
        cin>>N;
        if(N==0) return 0;

        vector<pair<int,int>> V(N);
        int sum=0;
        int sum2=0;

        for(int i=0;i<N;i++){
            cin>>V[i].first>>V[i].second;
            sum+=V[i].first;
            sum2+=V[i].second;
        }
        fill(dp[0],dp[N+1],false);
        sort(V.begin(),V.end(),greater<pair<int,int>>() );

        //場合分け
        if(sum-V[0].first>=V[0].first){
            cout<<sum+sum2<<endl;
        }else{
            //待ち時間
            int wait=V[0].first-(sum-V[0].first);
            dp[0][0]=true;
            for(int i=1;i<=N-1;i++){
                for(int j=0;j<=wait;j++){
                    if(!dp[i-1][j]) continue;
                    dp[i][j]=true;
                    if(j+V[i].second>wait) continue;
                    dp[i][j+V[i].second]=true;
                }
            }
            int ret=0;
            for(int i=0;i<=wait;i++){
                if(!dp[N-1][i]) continue;
                chmax(ret,i);
            }
            cout<<(wait-ret)+sum+sum2<<endl;
        }
    }
}
accuracy: 1
time_ms: 10
memory_kb: 4264
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define all(x) (x).begin(),(x).end()
#define YES() printf("YES\n")
#define NO() printf("NO\n")
#define isYES(x) printf("%s\n",(x) ? "YES" : "NO")
#define Yes() printf("Yes\n")
#define No() printf("No\n")
#define isYes(x) printf("%s\n",(x) ? "Yes" : "No")
#define isIn(x,y,h,w) (x >= 0 && x < h && y >= 0 && y < w)

#define int long long
//using ll = long long;
using P = pair<int,int>;

ostream &operator<<(ostream &os,const P &p){ return os << "(" << p.first << "," << p.second << ")"; }

template<class T> T &chmin(T &a,const T &b){ return a = min(a,b); }
template<class T> T &chmax(T &a,const T &b){ return a = max(a,b); }
 
const int INF=1e+18;
const double EPS=1e-9;
const int MOD=1000000007;

const int dx[]={1,0,-1,0},dy[]={0,-1,0,1};

int n;

void solve(){
	int r[1010],w[1010],sumr = 0,sumw = 0;
	vector<P> vec;
	for(int i = 0;i < n;i++){
		cin >> r[i] >> w[i];
		vec.emplace_back(r[i],w[i]);
		sumr += r[i];
		sumw += w[i];
	}
	sort(all(vec));
	for(int i = 0;i < n;i++){
		r[i] = vec[i].first;
		w[i] = vec[i].second;
	}
	if(sumr >= r[n - 1] * 2){
		cout << sumr + sumw << endl;
		return;
	}
	bool dp[1010][1010] = {};
	dp[0][0] = true;
	for(int i = 0;i < n - 1;i++){
		for(int j = 0;j <= 1000;j++){
			dp[i + 1][j] = dp[i][j] | ((j >= w[i]) ? dp[i][j - w[i]] : false);
		}
	}
	int ma = 0;
	for(int i = 0;i <= 2 * r[n - 1] - sumr;i++){
		if(dp[n - 1][i]) chmax(ma,i);
	}
	cout << 2 * r[n - 1] + sumw - ma << endl;
}

signed main(){
	while(cin >> n,n) solve();
}
accuracy: 1
time_ms: 10
memory_kb: 4156
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;

struct data {
  long long r, w;
  bool operator<(const data &p) { return r > p.r; }
};

long long n;
vector<data> v;
vector<vector<bool>> dp;

long long solve();

int main() {
  while(cin >> n, n) {
    v.resize(n);
    for(int i = 0; i < n; ++i) cin >> v[i].r >> v[i].w;
    sort(v.begin(), v.end());
    cout << solve() << endl;
  }
  return 0;
}

long long solve() {
  long long rsum = 0, wsum = 0, now = 0;
  for(int i = 0; i < n; ++i) {
    rsum += v[i].r;
    wsum += v[i].w;
  }
  now = max(0LL, 2 * v[0].r - rsum);
  dp.assign(n + 1, vector<bool>(now + 1, 0));
  dp[1][0] = 1;
  for(int i = 1; i < n; ++i)
    for(int j = 0; j <= now; ++j) {
      dp[i + 1][j] = dp[i][j];
      if(j >= v[i].w && dp[i][j - v[i].w]) dp[i + 1][j] = 1;
    }
  for(int i = now; i >= 0; --i)
    if(dp[n][i]) {
      now -= i;
      break;
    }
  return max(rsum + wsum, rsum + wsum + now);
}
accuracy: 1
time_ms: 10
memory_kb: 3240
final_rank: 4

code_snippet: #include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cctype>
#include<math.h>
#include<string>
#include<string.h>
#include<stack>
#include<queue>
#include<vector>
#include<utility>
#include<set>
#include<map>
#include<stdlib.h>
#include<iomanip>

using namespace std;

#define ll long long
#define ld long double
#define EPS 0.0000000001
#define INF 1e9
#define LINF (ll)INF*INF
#define MOD 1000000007
#define rep(i,n) for(int i=0;i<(n);i++)
#define loop(i,a,n) for(int i=a;i<(n);i++)
#define all(in) in.begin(),in.end()
#define shosu(x) fixed<<setprecision(x)

#define int ll //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int,int> pii;
typedef vector<pii> vp;

int gcd(int a, int b){
    if(b==0) return a;
    return gcd(b,a%b);
}
int lcm(int a, int b){
    return a/gcd(a,b)*b;
}

int dp[1010][3010] = {};

signed main(void) {
    int n;
    while(cin >> n,n){
        vp v(n);
        rep(i,n)cin >> v[i].first >> v[i].second;
        sort(all(v));
        int sumr = 0, sumw = 0;
        rep(i,n){
            sumr += v[i].first;
            sumw += v[i].second;
        }
        int ma = v.back().first;
        if(ma <= sumr - ma){
            cout << sumr + sumw << endl;
        }else{
            rep(i,1010)rep(j,3010)dp[i][j] = 0;
            dp[0][0] = 1;
            int MAX = 2*ma-sumr+1;
            rep(i,n)rep(j,MAX){
                dp[i+1][j] += dp[i][j];
                if(j+v[i].second < MAX && i < n-1){
                    dp[i+1][j+v[i].second] += dp[i][j];
                }
            }
            int tmp = -1;
            rep(i,MAX)if(dp[n][i])tmp = max(tmp, i);
            cout << ma*2 + sumw - tmp << endl;
        }
    }
}
accuracy: 1
time_ms: 120
memory_kb: 26864
final_rank: 20

code_snippet: #include <iostream>
#include <string>
#include <map>
#include <cstring>
#include <vector>

int N;

int R[1010], W[1010];

int dp[2020];
int main() {
    for(;;) {
        std::cin >> N;

        if(N == 0) {
            return 0;
        }

        int sum = 0;
        for(int i = 0; i < N; ++i) {
            std::cin >> R[i] >> W[i];

            sum += R[i];
        }

        int overHalf = -1;
        for(int i = 0; i < N; ++i) {
            if(R[i] * 2 > sum) {
                overHalf = i;
                break;
            }
        }

        if(overHalf == -1) {
            for(int i = 0; i < N; ++i) {
                sum += W[i];
            }

            std::cout << sum << std::endl;

            continue;
        }

        int reading = R[overHalf] * 2;

        memset(dp, 0, sizeof(dp));
        dp[0] = 1;
        for(int i = 0; i < N; ++i) {
            if(i == overHalf)
                continue;
            for(int j = 2000; j >= 0; --j) {
                if(W[i] + j <= 1500)
                    dp[j + W[i]] = dp[j + W[i]] || dp[j];
            }
        }

        int cut;
        for(int i = R[overHalf] - (sum - R[overHalf]); i >= 0; --i) {
            if(dp[i]) {
                cut = i;
                break;
            }
        }

        int writing = 0;
        for(int i = 0; i < N; ++i) {
            writing += W[i];
        }

        std::cout << reading + (writing - cut) << std::endl;
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3104
final_rank: 1

code_snippet: #include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <cfloat>
#include <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <functional>
#include <bitset>

using namespace std;
#define int long long int
const int INF = 1001001001001001LL;
const int MOD = 1000000007;

int di[] = {-1, 0, 1, 0, -1, 1, 1, -1};
int dj[] = {0, 1, 0, -1, 1, 1, -1, -1};

signed main(){
    
    while(1){
        int n; cin >> n;
        if(!n) break;
        vector<int> r(n);
        vector<int> w(n);
        vector<pair<int, int>> vec(n);
        for(int i = 0; i < n; i++){
            cin >> r[i] >> w[i];
            vec[i] = pair<int, int>(r[i], w[i]);
        }

        sort(vec.begin(), vec.end());
    
        int longest = vec[n - 1].first;
        int sumOfOthers = 0;
        for(int i = 0; i < n - 1; i++) sumOfOthers += vec[i].first;

        int ans = 0;
        for(int i = 0; i < n; i++) ans += vec[i].first + vec[i].second;
        
        if(longest <= sumOfOthers){
            // みっちりやる
        }else{
            int rest = longest - sumOfOthers;
            vector<int> v(n - 1);
            for(int i = 0; i < n - 1; i++) v[i] = vec[i].second;

            ans += rest;

            vector<vector<bool>> dp(n, vector<bool> (rest + 1, false));
            dp[0][0] = true;
            for(int i = 0; i < n - 1; i++){
                for(int j = 0; j <= rest; j++){
                    if(!dp[i][j]) continue;
                    int nj = j + v[i];
                    dp[i + 1][j] = true;
                    if(nj <= rest) dp[i + 1][nj] = true;
                }
            }

            int val = 0;
            for(int j = 0; j <= rest; j++) if(dp[n - 1][j]) val = j;
            ans -= val;
        }
        cout << ans << endl;
        
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3172
final_rank: 2

code_snippet: #include "bits/stdc++.h"
using namespace std;
typedef pair<int,int> P;

P book[1000];
bool dp[1000][1001]; //時間jをちょうど使ってi冊目までを適切に選んで感想を書けるか
int solve(int n)
{
	int ret=0;
	sort(book,book+n);
	int sum=0;
	for(int i=0;i<n-1;i++)
		sum+=book[i].first;
	if(sum<book[n-1].first)
	{
		ret=book[n-1].first*2;
		//1冊がとても重い場合スキマ時間になるべく感想を詰め込む
		int suki=book[n-1].first-sum; //スキマ時間の量
		fill(dp[0],dp[1000],false);
		dp[0][0]=true;
		for(int i=1;i<n;i++)
		{
			for(int j=0;j<1001;j++)
			{
				if(dp[i-1][j])
				{
					dp[i][j]=true;
					if(j+book[i-1].second<=suki)
						dp[i][j+book[i-1].second]=true;
				}
			}
		}
		int del=0;
		for(int i=0;i<=suki;i++)
		{
			if(dp[n-1][i])
				del=i;
		}
		sum=0;
		//感想の総時間を求める
		for(int i=0;i<n;i++)
			sum+=book[i].second;
		ret+=(sum-del);
	}else{
		//同時にすべての本が読み終わる場合感想は同時に書ける
		ret=sum+book[n-1].first;
		for(int i=0;i<n;i++)
			ret+=book[i].second;
	}
	return ret;
}

int main()
{
	while(1)
	{
		int n;
		cin>>n;
		if(n==0)
			break;
		for(int i=0;i<n;i++)
		{
			int r,w;
			cin>>r>>w;
			book[i]=P(r,w);
		}
		cout<<solve(n)<<endl;
	}
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 4056
final_rank: 8

code_snippet: #include <bits/stdc++.h>

using namespace std;
typedef long long int LL;
typedef long long int ll;
typedef pair<long long int, long long int> pii;
typedef pair<double, double> pdd;

#define SORT(c) sort((c).begin(),(c).end())
#define BACKSORT(c) sort((c).begin(),(c).end(),std::greater<LL>())
#define FOR(i,a,b) for(LL i=(a);i<(b);++i)
#define REP(i,n)  FOR(i,0,n)
#define SP << " " <<

LL mod = 1000000007;

int xcomp(pii& a, pii& b) {
	return a.first < b.first;
}

#define XSORT(c) sort((c).begin(),(c).end(),xcomp)

int main()
{
  cin.tie(0);
  ios::sync_with_stdio(false);
  while(true){
  LL N;
  cin >> N;
  if(N==0){
    break;
  }
  vector<pair<LL, LL>> rw;
  LL r_sum = 0;
  LL w_sum = 0;
  REP(i, N)
  {
    LL r,w;
    cin >> r >> w;
    rw.push_back({r, w});
    r_sum += r;
    w_sum += w;
  }
  XSORT(rw);
  if(r_sum-rw[rw.size()-1].first<rw[rw.size()-1].first){
    LL r_space = rw[rw.size() - 1].first - (r_sum - rw[rw.size() - 1].first);
    auto rw_rmax = rw[rw.size() - 1];
    rw.pop_back();

    vector<bool> hoge(2001, false);
    hoge[0] = true;
    REP(i, rw.size())
    {
      for (int j = 1000; j >= 0;--j){
        hoge[j + rw[i].second]= hoge[j + rw[i].second] || hoge[j];
      }
    }

    LL max = 0;
    
    REP(i,r_space+1){
      if(hoge[i]){
        max = i;
      }
    }

    cout << rw_rmax.first * 2 + w_sum - max << endl;
  }
  else
  {
    cout << r_sum + w_sum << endl;
  }
  }
}
accuracy: 1
time_ms: 10
memory_kb: 3212
final_rank: 3

code_snippet: // Ryo Kamoi
// #define DEBUG

#include<iostream>
#include<math.h>
#include<vector>
#include<string>
#include<algorithm>
#include<map>
#include<queue>

using namespace std;

#define REP(i, n) for(int i=0; i<n; i++)

typedef pair<int, int> pii;
typedef long long ll;
typedef pair<ll, ll> pll;

int INF = 1000000000;

int n;
vector<int> r, w;
int dp[1010][1010];
int res_sum, full_time;

int solve(int idx, int time) {
  if (dp[idx][time] >=0) return dp[idx][time];

  if (idx == 0) {
    if (time >= w[idx]) {
      return dp[idx][time] = w[idx];
    } else {
      return dp[idx][time] = 0;
    }
  }

  if (time < w[idx]) {
    return solve(idx-1, time);
  }

  return dp[idx][time] = max(
      solve(idx-1, time),
      solve(idx-1, time-w[idx]) + w[idx]
      );
}

int main(){
  while(1) {
    cin >> n;
    if (n==0) break;

    r = vector<int>();
    w = vector<int>();
    REP(i, n) {
      REP(j, 1001) {
        dp[i][j] = -1;
      }
    }


    REP(i, n) {
      int ri, wi;
      cin >> ri >> wi;
      r.push_back(ri);
      w.push_back(wi);
    }

    sort(r.begin(), r.end());
    sort(w.begin(), w.end());

    if (n==1) {
      cout << r[0] * 2 + w[0] << endl;
      continue;
    }
    
    res_sum = 0;
    REP(i, n-1) {
      res_sum += r[i];
    }

    full_time = 0;
    REP(i, n) {
      full_time += r[i] + w[i];
    }

    if (res_sum >= r[n-1]) {
      cout << full_time << endl;
    } else {
      int fill_gap = solve(n-2, r[n-1] - res_sum);
#ifdef DEBUG
      cout << r[n-1]-res_sum << " " << fill_gap << endl;
#endif
      cout << full_time + (r[n-1] - res_sum - fill_gap) << endl;
    }
  }
}
accuracy: 1
time_ms: 10
memory_kb: 7156
final_rank: 15

code_snippet: #include <iostream>
using namespace std;

int N;
int R[1010],W[1010];
bool dp[1010][1010];
int main(){
    while(true){
        cin >> N;
        if(N==0) break;
        int sumr = 0,sumw = 0,ma = 0,id = -1;
        for(int i=1;i<=N;i++){
            cin >> R[i] >> W[i];
            sumr += R[i];
            sumw += W[i];
            if(ma<R[i]){
                ma = R[i];
                id = i;
            }
        }
        if(2*ma<=sumr){
            cout << sumr+sumw << endl;
            continue;
        }
        for(int i=1;i<=N;i++) for(int j=0;j<=1000;j++) dp[i][j] = false;
        dp[0][0] = true;
        for(int i=1;i<=N;i++){
            for(int j=0;j<=1000;j++){
                dp[i][j] = (dp[i][j] | dp[i-1][j]);
                if(i!=id) dp[i][min(j+W[i],1000)] = (dp[i][min(j+W[i],1000)] | dp[i-1][j]);
            }
        }
        int ok_max = 0;
        for(int j=0;j<=2*ma-sumr;j++) if(dp[N][j]) ok_max = j;
        cout << max(sumr+sumw,2*ma+sumw-ok_max) << endl;
    }
}
accuracy: 1
time_ms: 10
memory_kb: 4064
final_rank: 9