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: Accepted)

#include<queue>
#include<cstdio>
#include<algorithm>

#define rep(i,n) for(int i=0;i<(n);i++)

using namespace std;

int hash(const vector<int> &a){
	int n=a.size();
	int res=0,fac=1;
	rep(i,n){
		int c=0;
		for(int j=i+1;j<n;j++) if(a[i]<a[j]) c++;
		res+=c*fac;
		fac*=n-i;
	}
	return res;
}

void bfs(vector<int> a,char *memo){
	int n=a.size();
	memo[hash(a)]=0;
	queue< pair<int,vector<int> > > Q; Q.push(make_pair(0,a));
	while(!Q.empty()){
		int t=Q.front().first;
		vector<int> a=Q.front().second; Q.pop();

		if(t==4) break;

		rep(l,n) for(int r=l+1;r<n;r++) {
			reverse(a.begin()+l,a.begin()+r+1);
			int h=hash(a);
			if(memo[h]>t+1){
				memo[h]=t+1;
				Q.push(make_pair(t+1,a));
			}
			reverse(a.begin()+l,a.begin()+r+1);
		}
	}
}

int main(){
	int n; scanf("%d",&n);
	int fact=1;
	vector<int> a(n);
	rep(i,n) scanf("%d",&a[i]), fact*=i+1;

	static char memo1[3628800],memo2[3628800];
	rep(i,fact) memo1[i]=memo2[i]=20;
	bfs(a,memo1);
	sort(a.begin(),a.end());
	bfs(a,memo2);

	int ans=9;
	rep(i,fact) ans=min(ans,memo1[i]+memo2[i]);
	printf("%d\n",ans);

	return 0;
}