AcWing 180. 排书
原题链接
中等
作者:
郡呈
,
2020-05-20 10:59:13
,
所有人可见
,
阅读 779
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 20;
int n;
int q[N];
int w[5][N];
int f() {
int cnt = 0;
for(int i = 0; i + 1 < n; i++)
if(q[i+1] != q[i]+1)
cnt++;
return (cnt + 2)/3;
}
bool dfs(int depth, int max_depth) {
if(depth + f() > max_depth) return false;
if(f() == 0) return true;
for(int len = 1; len <= n; len++) {
//枚举连续区间的长度
for(int l = 0; l + len - 1 < n; l++) {
//连续区间的开始节点
int r = l + len - 1;
//连续区间的右端点
for(int j = r + 1; j < n; j++) {
//枚举选择插入的位置
memcpy(w[depth], q, sizeof q);
int y = l;
for(int x = r+1; x <= j; x++, y++) q[y] = w[depth][x];
for(int x = l; x <= r; x++, y++) q[y] = w[depth][x];
//切换两段数据单元
if(dfs(depth+1, max_depth)) return true;
memcpy(q, w[depth], sizeof q);
}
}
}
return false;
}
int main() {
int T;
cin >> T;
while(T--) {
cin >> n;
for(int i = 0; i < n; i++) cin >> q[i];
int depth = 0;
while(depth < 5 && !dfs(0, depth)) depth++;
if(depth >= 5) cout << "5 or more" << endl;
else cout << depth << endl;
}
return 0;
}