voidreverse(int l, int r) { for (int i = l, j = r; i <= j; i++, j--) { swap(num[i], num[j]); } }
intevaluate() { int cnt = 0; for (int i = 1; i <= n; i++) { if (abs(num[i] - num[i - 1]) != 1) cnt++; } /* 注意当第一个元素不为 1 时也会让最小期望翻转次数加一 但第一个元素不应和不存在的第 0 个元素一起翻转 所以应当减去 1 */ return cnt - 1; }
booldfs(int depth, int maxd) { if (depth > maxd) return0; int v = evaluate(); if (depth + v > maxd) { return0; }
bool flag = 1; for (int i = n; i >= 1; i--) {//从最底层开始,优化搜索顺序 if (num[i] == i && flag) { if (i == 1) return1; continue;//已经有序的不用继续排了 } flag = 0; reverse(1, i); if (dfs(depth + 1, maxd)) { return1; } reverse(1, i); }
return0; }
intmain() { cin >> n; for (int i = 1; i <= n; i++) { cin >> num[i]; id[i] = i; }
//离散化操作,将铁盘半径转化为应当处于的位置 sort(id + 1, id + n + 1, cmp); for (int i = 1; i <= n; i++) { num[id[i]] = i; }
for (int maxd = evaluate();; maxd++) {//从预估翻转次数开始搜索 if (dfs(0, maxd)) { cout << maxd << endl; break; } }