<|instruction|>
Solve the below problem. The solution should start with an abridged problem statement. Then key observations. Then full solution based on the observations. Then C++ and Python implementations with comments.

259. Printed PR
time limit per test: 0.25 sec.
memory limit per test: 65536 KB
input: standard
output: standard



Small PR-agency got an order to print a very big lot of agitational materials. Agency should print and deliver N leaflets. Agency is very small and has only one printer, but it can print any leaflet. Leaflets can be different, so it is possible that times of printing of leaflets will differ. To print i-th leaflet the printer needs Ti minutes. When leaflet is printed, it should be immediately delivered to its addressee. The agency has unlimited number of couriers, so the courier gets the leaflet as soon as it printed and goes to the addressee. It takes Li minutes to deliver i-th leaflet. You were hired by agency to calculate the minimal time required to finish the job (this is an interval of time from the beginning of printing to the moment when the last leaflet is delivered), considering that the leaflets can be printed in any order.

Input
The first line contains a number of leaflets - integer number N (1 <= N <= 100). The second line contains N integer numbers Ti (1 <= i <= N). Third line contains N integer numbers Li (1 <= i <= N). You can assume that 1 <= Ti, Li <= 1000.

Output
You should output only one number - the answer for the problem.

Sample test(s)

Input
2
2 1
2 1

Output
4
Author:	Ilya V. Elterman
Resource:	Saratov SU Contest: Golden Fall 2004
Date:	October 2, 2004

<|response|>
1. Abridged problem statement
We have N leaflets to print and deliver. Printing leaflet i takes T_i minutes (one printer, jobs in sequence). As soon as a leaflet is printed, a courier departs immediately and takes L_i minutes to deliver it (unlimited couriers). Find the minimal time from start of printing until the last delivery is completed, by choosing the print order optimally.

2. Key observations
- Let C_i be the time printing of job i finishes (cumulative sum of preceding T’s plus T_i). The delivery of i finishes at time C_i + L_i. We want to minimize max_i(C_i + L_i).
- For any two jobs i and j, compare the schedule i→j versus j→i:
  • i→j makespan = max( T_i+L_i, (T_i+T_j)+L_j )
  • j→i makespan = max( T_j+L_j, (T_j+T_i)+L_i )
  One can show the better order is to print first the job with larger L (delivery time).
- Therefore the optimal rule is to sort jobs in non-increasing order of L_i (ties can be broken arbitrarily, e.g. by printing time or original index). Equivalently, sort by the pairwise comparator above directly.

3. Full solution approach
a. Read N and arrays T[ ] and L[ ].
b. Create a list of pairs (T_i, L_i).
c. Sort this list by the pairwise comparator (equivalently, descending order of L_i).
d. Initialize two integers: current_print_time = 0, answer = 0.
e. For each job in the sorted list:
   - current_print_time += T_i
   - answer = max(answer, current_print_time + L_i)
f. Print answer.

Time complexity is O(N log N) for sorting, N ≤ 100.

4. C++ implementation
```cpp
#include <bits/stdc++.h>

using namespace std;

template<typename T1, typename T2>
ostream &operator<<(ostream &out, const pair<T1, T2> &x) {
    return out << x.first << ' ' << x.second;
}

template<typename T1, typename T2>
istream &operator>>(istream &in, pair<T1, T2> &x) {
    return in >> x.first >> x.second;
}

template<typename T>
istream &operator>>(istream &in, vector<T> &a) {
    for(auto &x: a) {
        in >> x;
    }
    return in;
};

template<typename T>
ostream &operator<<(ostream &out, const vector<T> &a) {
    for(auto x: a) {
        out << x << ' ';
    }
    return out;
};

int n;
vector<pair<int, int>> a;

void read() {
    cin >> n;
    a.resize(n);
    for(int i = 0; i < n; i++) {
        cin >> a[i].first;
    }
    for(int i = 0; i < n; i++) {
        cin >> a[i].second;
    }
}

void solve() {
    // Current time: max(a1 + b1, a1 + a2 + b2)
    // Alternative time: max(a2 + b2, a2 + a1 + b1)
    //      -= a1 + a2
    // Current time: max(b1 - a2, b2)
    // Alternative time: max(b2 - a1, b1)
    //       If b1 - a2 > b2
    //             Current time: b1 - a2
    //             Alternative time: b1         -> Alternative time is longer
    //       If b1 - a2 < b2
    //             Current time: b2
    //             Alternative time: max(b2 - a1, b1)
    //                                          -> Alternative time is better
    //                                          only
    //                                             if b1 < b2

    // Current time: max(a1 + b1, a1 + a2 + b2)
    // Alternative time: max(a2 + b2, a2 + a1 + b1)
    // -> b1 < b2
    //    Current time: a1 + b1 + b2
    //    Alternative time: max(a1 + a2 + b1, a2 + b2) < a1 + b1 + b2
    // -> b1 > b2
    //    Current time: max(a1 + b1, a1 + a2 + b2)
    //    Alternative time: a1 + a2 + b1 > Current time

    stable_sort(
        a.begin(), a.end(),
        [](const pair<int, int> &x, const pair<int, int> &y) {
            return max(x.first + x.second, x.first + y.first + y.second) <
                   max(y.first + y.second, y.first + x.first + x.second);
        }
    );

    int ans = 0, sum = 0;
    for(int i = 0; i < n; i++) {
        sum += a[i].first;
        ans = max(ans, sum + a[i].second);
    }

    cout << ans << '\n';
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    int T = 1;
    // cin >> T;
    for(int test = 1; test <= T; test++) {
        read();
        // cout << "Case #" << test << ": ";
        solve();
    }

    return 0;
}
```

5. Python implementation
```python
import sys

def main():
    data = sys.stdin.read().split()
    it = iter(data)

    # Read input
    N = int(next(it))
    T = [int(next(it)) for _ in range(N)]
    L = [int(next(it)) for _ in range(N)]

    # Pair each job as (T_i, L_i)
    jobs = list(zip(T, L))

    # Sort by descending delivery time L_i
    jobs.sort(key=lambda job: job[1], reverse=True)

    current_print = 0  # cumulative printing time
    answer = 0         # will hold the makespan

    # Process jobs in sorted order
    for t, l in jobs:
        current_print += t
        # Delivery of this job completes at current_print + l
        if current_print + l > answer:
            answer = current_print + l

    # Output the minimal possible makespan
    print(answer)

if __name__ == "__main__":
    main()
```
