Problem p02587 (C++) — buggy submission, verdict: Runtime Error

#include <algorithm>
#include <iostream>
#include <map>
#include <string>
using namespace std;
const int BUF = 55;
const long long INF = 1LL << 60;

int nStr;
string s[BUF];
int cost[BUF];

void read() {
  cin >> nStr;
  for (int i = 0; i < nStr; ++i) {
    cin >> s[i] >> cost[i];
  }
}

bool isPalindrome(string &str) {
  for (int i = 0; i < str.size() / 2; ++i) {
    if (str[i] != str[str.size() - 1 - i]) {
      return false;
    }
  }
  return true;
}

bool aStartsWithB(string &a, string &b) {
  return a.size() >= b.size() && a.substr(0, b.size()) == b;
}

bool aEndsWithB(string &a, string &b) {
  return a.size() >= b.size() && a.substr(a.size() - b.size()) == b;
}

long long rec(string bgn, string end,
              map<pair<string, string>, long long> &dp) {
  if (dp.count(make_pair(bgn, end))) {
    return dp[make_pair(bgn, end)];
  }

  if ((bgn.empty() && isPalindrome(end)) ||
      (end.empty() && isPalindrome(bgn))) {
    return dp[make_pair(bgn, end)] = 0;
  }

  dp[make_pair(bgn, end)] = INF;
  long long ret = INF;

  if (bgn.empty()) {
    for (int i = 0; i < nStr; ++i) {
      string &str = s[i];
      if (aEndsWithB(str, end)) {
        string nextBgn = str.substr(0, str.size() - end.size());
        reverse(nextBgn.begin(), nextBgn.end());
        ret = min(ret, rec(nextBgn, "", dp) + cost[i]);
      } else if (aEndsWithB(end, str)) {
        ret = min(ret, rec("", end.substr(0, end.size() - str.size()), dp) +
                           cost[i]);
      }
    }
  } else {
    for (int i = 0; i < nStr; ++i) {
      string &str = s[i];
      if (aStartsWithB(str, bgn)) {
        string nextEnd = str.substr(bgn.size());
        reverse(nextEnd.begin(), nextEnd.end());
        ret = min(ret, rec("", nextEnd, dp) + cost[i]);
      } else if (aStartsWithB(bgn, str)) {
        ret = min(ret, rec(bgn.substr(str.size()), "", dp) + cost[i]);
      }
    }
  }

  return dp[make_pair(bgn, end)] = ret;
}

void work() {
  long long minV = INF;

  map<pair<string, string>, long long> dp;
  for (int i = 0; i < nStr; ++i) {
    string nextEnd = s[i];
    reverse(nextEnd.begin(), nextEnd.end());
    minV = min(minV, rec("", nextEnd, dp) + cost[i]);
  }

  cout << (minV == INF ? -1 : minV) << endl;
}

int main() {
  read();
  work();
  return 0;
}


Error: 0

Fixed submission:

#include <algorithm>
#include <iostream>
#include <map>
#include <string>
using namespace std;
const int BUF = 55;
const long long INF = 1LL << 60;

int nStr;
string s[BUF];
int cost[BUF];

void read() {
  cin >> nStr;
  for (int i = 0; i < nStr; ++i) {
    cin >> s[i] >> cost[i];
  }
}

bool isPalindrome(const string &str) {
  for (int i = 0; i < str.size() / 2; ++i) {
    if (str[i] != str[str.size() - 1 - i]) {
      return false;
    }
  }
  return true;
}

bool aStartsWithB(const string &a, const string &b) {
  return a.size() >= b.size() && a.substr(0, b.size()) == b;
}

bool aEndsWithB(const string &a, const string &b) {
  return a.size() >= b.size() && a.substr(a.size() - b.size()) == b;
}

long long rec(const string &bgn, const string &end,
              map<pair<string, string>, long long> &dp) {
  if (dp.count(make_pair(bgn, end))) {
    return dp[make_pair(bgn, end)];
  }

  if ((bgn.empty() && isPalindrome(end)) ||
      (end.empty() && isPalindrome(bgn))) {
    return dp[make_pair(bgn, end)] = 0;
  }

  long long ret = INF;

  if (bgn.empty()) {
    for (int i = 0; i < nStr; ++i) {
      string &str = s[i];
      if (aEndsWithB(str, end)) {
        string nextBgn = str.substr(0, str.size() - end.size());
        reverse(nextBgn.begin(), nextBgn.end());
        ret = min(ret, rec(nextBgn, "", dp) + cost[i]);
      } else if (aEndsWithB(end, str)) {
        ret = min(ret, rec("", end.substr(0, end.size() - str.size()), dp) +
                           cost[i]);
      }
    }
  } else {
    for (int i = 0; i < nStr; ++i) {
      string &str = s[i];
      if (aStartsWithB(str, bgn)) {
        string nextEnd = str.substr(bgn.size());
        reverse(nextEnd.begin(), nextEnd.end());
        ret = min(ret, rec("", nextEnd, dp) + cost[i]);
      } else if (aStartsWithB(bgn, str)) {
        ret = min(ret, rec(bgn.substr(str.size()), "", dp) + cost[i]);
      }
    }
  }

  return dp[make_pair(bgn, end)] = ret;
}

void work() {
  long long minV = INF;

  map<pair<string, string>, long long> dp;
  for (int i = 0; i < nStr; ++i) {
    string nextEnd = s[i];
    reverse(nextEnd.begin(), nextEnd.end());
    minV = min(minV, rec("", nextEnd, dp) + cost[i]);
  }

  cout << (minV == INF ? -1 : minV) << endl;
}

int main() {
  read();
  work();
  return 0;
}