Problem:
Reverse Sort

1 ∼ NまでのN個の数字の順列A1, A2, ……, ANが与えられる。
この順列に対して区間[i, j](1 ≤ i ≤ j ≤ N)の数字の順序を逆順にする操作reverse(i, j)を行うことが出来る。
例えば、[1, 2, 3, 4, 5]に対してreverse(2, 4)を適用すると[1, 4, 3, 2, 5]となる。
最小で何回の操作を行えば順列を昇順にソートされた状態にすることが出来るか計算せよ。

Input

入力は以下の形式で与えられる。

N
A1 A2 …… AN

Constraints

Nは整数である

2 ≤ N ≤ 10

Output

問題の解を1行に出力せよ。

Sample Input 1

5
1 4 3 5 2

Output for the Sample Input 1

2

reverse(4,5):1 4 3 2 5

reverse(2,4):1 2 3 4 5

のようにすればよい。

Sample Input 2

5
3 1 5 2 4

Output for the Sample Input 2

4

例えば

reverse(1,2):1 3 5 2 4

reverse(3,5):1 3 4 2 5

reverse(2,4):1 2 4 3 5

reverse(3,4):1 2 3 4 5

のようにすればよい。

Sample Input 3

3
1 2 3

Output for the Sample Input 3

0

Sample Input 4

10
3 1 5 2 7 4 9 6 10 8

Output for the Sample Input 4

9

Solution in C++ (judge verdict: Memory Limit Exceeded)

#include<iostream>
#include<map>
#include<vector>
#include<algorithm>
#include<cassert>
#include<queue>
#include<cstdio>

#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define inf (1<<29)

using namespace std;

struct P
{
  vector<int> A;
  int cost;
  P(vector<int> A2=vector<int>(),int cost=inf):cost(cost)
  {
    A = A2;
  }

  bool operator < (const P& a)const
  {
    return cost > a.cost;
  }

};

int N;
map<vector<int>,int> mincost;
map<vector<int>,int> rmincost;
vector<int> initial;

void computeR(int step)
{
  priority_queue<P> Q;
  {
    initial.resize(N);
    rep(i,N)initial[i] = i+1;
    Q.push(P(initial,0));
    rmincost[initial] = 0;
  }

  while(!Q.empty())
    {
      P p = Q.top(); Q.pop();
      if(p.cost > step)continue;

      rep(s,N)
	{
	  REP(t,s+2,N+1)
	    {
	      vector<int> next = p.A;
	      reverse(next.begin()+s,next.begin()+t);
	      if(rmincost.find(next) == rmincost.end())
		{
		  rmincost[next] = p.cost + 1;
		  Q.push(P(next,p.cost+1));
		}
	    }
	}

    }
}

void compute(vector<int> &vec)
{
  mincost[vec] = 0;
  priority_queue<P> Q;
  Q.push(P(vec,0));

  int ans = inf;

  while(!Q.empty())
    {
      P p = Q.top(); Q.pop();

      if(p.cost >= ans)continue;

      if(rmincost.find(p.A) != rmincost.end())
	{
	  ans = min(ans,p.cost + rmincost[p.A]);
	  continue;
	}

      rep(s,N)
	{
	  REP(t,s+2,N+1)
	    {
	      vector<int> next = p.A;
	      reverse(next.begin()+s,next.begin()+t);
	      if(mincost.find(next) == mincost.end())
		{
		  mincost[next] = p.cost + 1;
		  Q.push(P(next,p.cost+1));
		}
	    }
	}
    }
  cout << ans << endl;
  assert(ans != inf);
}

int main()
{

  scanf("%d",&N);
  
  computeR((int)(N/2));
  //cout << "---------" << endl;
  vector<int> vec(N);
  rep(i,N)cin >> vec[i];

  compute(vec);


  return 0;
}