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

const int ms = 1e5+5;
const int inf = 0x3f3f3f3f;

int m[ms], f[ms];
int isEmpty[ms];

int dp[3005][3005][2][2];

main() {
  int n;
  cin >> n;
  int qntM = 0;
  for(int i = 0; i < n; i++) {
    cin >> m[i] >> f[i];
    qntM += m[i];
  }
  if(qntM == 0) {
    cout << 0 << '\n';
    return 0;
  }
  int empt = 0;
  for(int i = 0; i < n; i++) {
    if(m[i] == 0 && f[i] == 0) {
      isEmpty[i] = 1;
      empt++;
    }
  }
  for(int i = 0; i < n; i++) {
    if(isEmpty[i]) continue;
    f[i] = f[i] - 1;
  }
  for(int j = 0; j <= empt; j++) {
    dp[n][j][1][1] = 0;
    dp[n][j][0][1] = inf;
    dp[n][j][1][0] = inf;
    dp[n][j][0][0] = inf;
  }
  for(int i = n-1; i >= 0; i--) {
    for(int j = 0; j <= empt; j++) {
      for(int hasSo = 0; hasSo < 2; hasSo++) {
        for(int hasUm = 0; hasUm < 2; hasUm++) {
          int &ans = dp[i][j][hasSo][hasUm];
          ans = dp[i+1][j][hasSo][1] + m[i] + f[i];
          if(isEmpty[i] && j > 0) {
            ans = min(ans, dp[i+1][j-1][1][hasUm]);
          }
          if(!isEmpty[i]) {
            int k = min(j, m[i]); 
            ans = min(ans, dp[i+1][j-k][1][hasUm] + m[i] + m[i] - k);
          }
        }
      }
    }
  }
  cout << dp[0][empt][0][0] << endl;
}

kkk

#include <bits/stdc++.h>
#define N 3003
#define INF 1000000007
using namespace std;
int n, f[N];
struct pool { int m, f; } p[N];
bool cmp1(pool x, pool y) { return x.m + x.f > y.m + y.f; }
bool cmp2(pool x, pool y) { return x.f - x.m > y.f - y.m; }
int main() 
{
    scanf("%d", &n);
    int m = 0;
    bool flag = 1;
    for(int i = 1; i <= n; ++ i) 
    {
        scanf("%d%d", &p[i].m, &p[i].f);
        if(!p[i].m && !p[i].f) ++ m;
        if(p[i].m) flag = 0;
    }
    if(flag) { puts("0"); return 0; }
    sort(p + 1, p + n + 1, cmp1);
    n -= m;
    int sum = 0;
    for(int i = 1; i <= n; ++ i) sum += p[i].m + p[i].f - 1;
    if(!m) 
    {
        sort(p + 1, p + n + 1, cmp2);
        sum -= p[1].f - 1 - p[1].m;
        for(int i = 2; i < n; ++ i)
            if(p[i].f - 1 - p[i].m >= 0) sum -= p[i].f - 1 - p[i].m;
        printf("%d\n", sum);
        return 0;
    }
    for(int i = 1; i <= n; ++ i)
        for(int j = m; j >= p[i].m; -- j) f[j] = max(f[j], f[j - p[i].m] + p[i].f - 1);
    int ans = sum - f[m];
    sum -= m;
    int k = 0;
    for(int i = 1; i <= n; ++ i)
        if(p[i].f - 1 - p[i].m >= 0) sum -= p[i].f - 1 - p[i].m, k += p[i].m;
    if(k >= m) ans = min(ans, sum);
    else 
    {
        f[0] = 0;
        for(int i = 1; i <= m; ++ i) f[i] = -INF;
        for(int i = 1; i <= n; ++ i) if(p[i].f - 1 - p[i].m < 0)
        {
            for(int j = m; j >= 0 && j + p[i].m >= m; -- j) ans = min(ans, sum - f[j] - (p[i].f - 1 - p[i].m));
            for(int j = m; j >= p[i].m; -- j) f[j] = max(f[j], f[j - p[i].m] + p[i].f - 1 - p[i].m);
        }
    }
    printf("%d\n", ans);
    return 0;
}