1142. 排序
Constraints
Time Limit: 10 secs, Memory Limit: 32 MB
Description
通常我们对一个长度为n(n≤24)的整数数列进行排序操作,其实就是讲他们按照从小到大的顺序重整。一般情况下我们可以比较任意两个数之间的大小并交换他们的位置,但这里我们限制只能数列的某一个前缀序列翻转,除此之外的任何操作都是不允许的。更精确地说,假设数列a1,a2,……,an,一个合法的操作是把数列变为ak,ak-1,……,a2, a1, ak+1, ak+2,……, an,其中1<k≤n。例如:数列3 2 1 4,可能的操作有三种,分别是2 3 1 4、1 2 3 4、4 1 2 3。
你任务是求出一个序列用上面的方法排序至少需要多少步。
Input
输入文件有两行:
第一行是一个整数n,表示数列的长度。
第二行有n个整数,表示待排序的数列,每个整数的绝对值不大于32767。
Output
输出文件有一行是一个整数s,表示完成排序所需的最少步数。
Sample Input
43 2 1 4
Sample Output
1提示,只需要一步就可以完成排序:3 2 1 4  1 2 3 4。
Problem Source
ZSUACM Team Member
// Problem#: 1142
// Submission#: 3289813
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include <stdio.h>
#include <iostream>
#include <vector>
#include <string>
#include <stack>
#include <iomanip>
#include <algorithm>
#include <queue>
#include <functional>
using namespace std;
int s[30], num[30];
int N;
inline int minOpe() {
int ope = 0;
for (int i = 0; i < N - 1; i++) {
ope += (s[i] - s[i + 1] > 1 || s[i + 1] - s[i] > 1);
}
return ope;
}
inline bool check() {
for (int i = 0; i < N - 1; i++) {
if (s[i] > s[i + 1]) return false;
}
return true;
}
bool dfs(int now) {
if (now == 0) return check();
if (now < minOpe()) return false;
for (int i = 2; i <= N; i++) {
reverse(s, s + i);
if (dfs(now - 1)) return true;
reverse(s, s + i);
}
return false;
}
bool cmp(const int & a, const int & b) {
return num[a] < num[b];
}
int main() {
std::ios::sync_with_stdio(false);
cin >> N;
for (int i = 0; i < N; i++) {
cin >> num[i];
s[i] = i;
}
sort(s, s + N, cmp);
int ans = minOpe();
while (1) {
if (dfs(ans++)) break;
}
cout << ans - 1 << endl;
//cin >> N;
return 0;
}