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

#include <bits/stdc++.h>
#define REACH cout << __LINE__ << endl
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define REP(i, b) FOR(i, 0, b)
#define PB push_back
#define ALL(c) c.begin(), c.end()
#define MP make_pair
using namespace std;
typedef long long LL;
typedef long double ld;
typedef int ut;
typedef vector<ut> VI;
typedef pair<ut, ut> pr;
typedef pair<ut, pr> ppr;
typedef vector<pr> Vpr;
typedef pair<int, vector<int>> pqt;
typedef vector<pqt> Vpqt;
typedef priority_queue<pqt, Vpqt, greater<pqt>> PQ;
map<vector<int>, int> dists;
typedef pair<int, vector<int>> pvi;
const int SIZE = 20;
clock_t clocks[SIZE];
double clockst(int x) { clocks[x] = -clock(); }
double clocked(int x) { clocks[x] += clock(); }
double timer(int x) { return clocks[x]; }
void reverse(vector<int> &nums, int a, int b) {
  while (a < b) {
    swap(nums[a++], nums[b--]);
  }
}
/*int score(vector<int> &nums){
        int ables[2]={};
        REP(i,nums.size()){
                ables[abs(i+1-nums[i])&1]|=1;
        }
        return ables[0]+ables[1];
}*/
/*int score(vector<int> &nums){

        int ans=0;
        REP(i,nums.size()-1){
                if(i+1-nums[i]>0 && i+2-nums[i+1]<0) ans++;
        }

        return ans;

}*/
int score(vector<int> &nums) {
  //	return 0;
  int ans = 0, two = 0;
  REP(i, nums.size() - 1) {
    if (abs(nums[i + 1] - nums[i]) >= 2)
      two++;
  }
  FOR(i, 0, nums.size()) {
    if ((((i != nums.size() - 1) ? nums[i + 1] : (int)nums.size()) - nums[i]) *
            (nums[i] - (i ? nums[i - 1] : 0)) <
        0)
      ans++;
    //		cout << (((i!=nums.size()-1)?nums[i+1]:(int)nums.size())-nums[i]) << "
    //" <<  (nums[i]-(i?nums[i-1]:0)) << endl;
  }
  //	cout << ans << endl;
  return (max(two, ans) + 1) / 2;
}

int times = 0;
int solve(vector<int> nums) {
  clockst(2);

  PQ qu;

  vector<int> ans;
  REP(i, nums.size()) { ans.PB(i + 1); }
  qu.push(pvi(score(nums), nums));

  while (!qu.empty()) {
    vector<int> now = qu.top().second;
    int dist = qu.top().first - score(now);
    qu.pop();
    if (dist != dists[now])
      continue;
    times++;
    if (times == 160000)
      return nums.size() - 1;
    if (now == ans)
      return dists[ans];
    //		REP(i,now.size()) cout << now[i] << " ";
    //		cout <<dist << " "<< score(now) <<  endl;
    REP(i, nums.size()) {
      REP(j, i) {
        reverse(now, j, i);
        if (!dists.count(now) || dists[now] > dist + 1) {
          if (dist + 1 + score(now) < nums.size() - 1)
            qu.push(pvi(dist + 1 + score(now), vector<int>(now)));
          if (dist + 1 + score(now) < nums.size())
            dists[now] = dist + 1;
        }
        reverse(now, j, i);
      }
    }
  }

  return nums.size() - 1;
}
int main() {
  vector<int> vi;
  int n, x;

  cin >> n;
  REP(i, n) {
    cin >> x;
    vi.PB(x);
  }
  cout << solve(vi) << endl;
  clocked(2);
  // cout << times << endl;
  // cout << dists.size() << endl;
  // cout << timer(2) << endl;
  // cout << timer(1) << endl;

  // your code goes here
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define REACH cout << __LINE__ << endl
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define REP(i, b) FOR(i, 0, b)
#define PB push_back
#define ALL(c) c.begin(), c.end()
#define MP make_pair
using namespace std;
typedef long long LL;
typedef long double ld;
typedef int ut;
typedef vector<ut> VI;
typedef pair<ut, ut> pr;
typedef pair<ut, pr> ppr;
typedef vector<pr> Vpr;
typedef pair<int, vector<int>> pqt;
typedef vector<pqt> Vpqt;
typedef priority_queue<pqt, Vpqt, greater<pqt>> PQ;
map<vector<int>, int> dists;
typedef pair<int, vector<int>> pvi;
const int SIZE = 20;
clock_t clocks[SIZE];
double clockst(int x) { clocks[x] = -clock(); }
double clocked(int x) { clocks[x] += clock(); }
double timer(int x) { return clocks[x]; }
void reverse(vector<int> &nums, int a, int b) {
  while (a < b) {
    swap(nums[a++], nums[b--]);
  }
}
/*int score(vector<int> &nums){
        int ables[2]={};
        REP(i,nums.size()){
                ables[abs(i+1-nums[i])&1]|=1;
        }
        return ables[0]+ables[1];
}*/
/*int score(vector<int> &nums){

        int ans=0;
        REP(i,nums.size()-1){
                if(i+1-nums[i]>0 && i+2-nums[i+1]<0) ans++;
        }

        return ans;

}*/
int score(vector<int> &nums) {
  //	return 0;
  int ans = 0, two = 0;
  REP(i, nums.size() - 1) {
    if (abs(nums[i + 1] - nums[i]) >= 2)
      two++;
  }
  FOR(i, 0, nums.size()) {
    if ((((i != nums.size() - 1) ? nums[i + 1] : (int)nums.size()) - nums[i]) *
            (nums[i] - (i ? nums[i - 1] : 0)) <
        0)
      ans++;
    //		cout << (((i!=nums.size()-1)?nums[i+1]:(int)nums.size())-nums[i]) << "
    //" <<  (nums[i]-(i?nums[i-1]:0)) << endl;
  }
  //	cout << ans << endl;
  return (max(two, ans) + 1) / 2;
}

int times = 0;
int solve(vector<int> nums) {
  clockst(2);

  PQ qu;

  vector<int> ans;
  REP(i, nums.size()) { ans.PB(i + 1); }
  qu.push(pvi(score(nums), nums));

  while (!qu.empty()) {
    vector<int> now = qu.top().second;
    int dist = qu.top().first - score(now);
    qu.pop();
    if (dist != dists[now])
      continue;
    times++;
    if (times == 170000)
      return nums.size() - 1;
    if (now == ans)
      return dists[ans];
    //		REP(i,now.size()) cout << now[i] << " ";
    //		cout <<dist << " "<< score(now) <<  endl;
    REP(i, nums.size()) {
      REP(j, i) {
        reverse(now, j, i);
        if (!dists.count(now) || dists[now] > dist + 1) {
          if (dist + 1 + score(now) < nums.size() - 1)
            qu.push(pvi(dist + 1 + score(now), vector<int>(now)));
          if (dist + 1 + score(now) < nums.size())
            dists[now] = dist + 1;
        }
        reverse(now, j, i);
      }
    }
  }

  return nums.size() - 1;
}
int main() {
  vector<int> vi;
  int n, x;

  cin >> n;
  REP(i, n) {
    cin >> x;
    vi.PB(x);
  }
  cout << solve(vi) << endl;
  clocked(2);
  // cout << times << endl;
  // cout << dists.size() << endl;
  // cout << timer(2) << endl;
  // cout << timer(1) << endl;

  // your code goes here
  return 0;
}