Problem p00157 (C++) — buggy submission, verdict: Time Limit Exceeded

// AOJ 0157
#include <iostream>
#include <map>
#include <sstream>
#include <string>
#include <vector>
#define REP(i, n) for (int i = 0; i < (int)(n); i++)
using namespace std;
typedef pair<int, int> P;

const int NMAX = 150;

vector<P> ichiro, jiro;
int n, m;
int idp[NMAX], jdp[NMAX];
int index[NMAX], jndex[NMAX];
map<pair<int, int *>, int> table;

void init() {
  REP(i, NMAX) {
    idp[i] = jdp[i] = 0;
    index[i] = jndex[i] = 0;
  }
  jiro.clear();
  ichiro.clear();

  jiro.push_back(make_pair(0, 0));
  ichiro.push_back(make_pair(0, 0));
  table.clear();
}

bool bigger(P big, P small) {
  return (big.first > small.first and big.second > small.second);
}

int lowerb(P mine, vector<P> his) {
  int len = his.size();
  for (int i = 1; i < len; i++) {
    if (not bigger(mine, his[i])) {
      return i - 1;
    }
  }
  return len - 1;
}

int rec(int i, int *mine, int *his) {
  auto it = table.find(make_pair(i, mine));
  if (it != table.end()) {
    return it->second;
  }
  if (i == 0) {
    return 0;
  } else {
    int ans = 1 + max(rec(i - 1, mine, his), rec(mine[i], his, mine));
    table.insert(make_pair(make_pair(i, mine), ans));
    return ans;
  }
}

int solve() {
  for (int i = 1; i <= n; i++) {
    index[i] = lowerb(ichiro[i], jiro);
  }

  for (int j = 1; j <= m; j++) {
    jndex[j] = lowerb(jiro[j], ichiro);
  }

  return max(rec(n, index, jndex), rec(m, jndex, index));
}

int main() {
  while (cin >> n and n) {
    init();
    REP(i, n) {
      int h, r;
      cin >> h >> r;
      ichiro.push_back(make_pair(h, r));
    }

    cin >> m;
    REP(i, m) {
      int h, r;
      cin >> h >> r;
      jiro.push_back(make_pair(h, r));
    }

    cout << solve() << endl;
  }
}

Error: TLE

Fixed submission:

// AOJ 0157
#include <iostream>
#include <map>
#include <sstream>
#include <string>
#include <vector>
#define REP(i, n) for (int i = 0; i < (int)(n); i++)
using namespace std;
typedef pair<int, int> P;

const int NMAX = 150;

vector<P> ichiro, jiro;
int n, m;
int idp[NMAX], jdp[NMAX];
int index[NMAX], jndex[NMAX];

void init() {
  REP(i, NMAX) {
    idp[i] = jdp[i] = 0;
    index[i] = jndex[i] = 0;
  }
  jiro.clear();
  ichiro.clear();

  jiro.push_back(make_pair(0, 0));
  ichiro.push_back(make_pair(0, 0));
}

bool bigger(P big, P small) {
  return (big.first > small.first and big.second > small.second);
}

int lowerb(P mine, vector<P> his, int len) {
  for (int i = 1; i < len; i++) {
    if (not bigger(mine, his[i])) {
      return i - 1;
    }
  }
  return len - 1;
}

int rec(int i, int *mine, int *his) {
  if (i < 0)
    throw 1;
  if (i == 0) {
    return 0;
  } else {
    return 1 + max(rec(i - 1, mine, his), rec(mine[i], his, mine));
  }
}

int solve() {
  for (int i = 1; i <= n; i++) {
    index[i] = lowerb(ichiro[i], jiro, m);
  }

  for (int j = 1; j <= m; j++) {
    jndex[j] = lowerb(jiro[j], ichiro, n);
  }

  return max(rec(n, index, jndex), rec(m, jndex, index));
}

int main() {
  while (cin >> n and n) {
    init();
    REP(i, n) {
      int h, r;
      cin >> h >> r;
      ichiro.push_back(make_pair(h, r));
    }

    cin >> m;
    REP(i, m) {
      int h, r;
      cin >> h >> r;
      jiro.push_back(make_pair(h, r));
    }

    cout << solve() << endl;
  }
}