AcWing 180. 排书
IDA*算法,和迭代加深类似,多了一个预估值f()(最少还需要搜索多少部),还是限制搜索的层数,如果目前搜索的层数+预估的最小搜索层数都大于最大搜索层数要求,那么这个搜索肯定不和条件,就直接return false;
#include<bits/stdc++.h>
using namespace std;
const int N = 15;
int T;
int n;
int q[N];
int w[5][N];
int f(){
int res = 0;
for(int i = 0; i + 1 < n; i ++ ){
if(q[i + 1] != q[i] + 1) res ++ ;
}
return (res + 2) / 3;
}
bool check(){
for(int i = 0; i + 1 < n; i ++ ){
if(q[i + 1] != q[i] + 1) return false;
}
return true;
}
bool dfs(int depth, int max_depth){
if(f() + depth > max_depth) return false;
if(check()) return true;
for(int len = 1; len <= n; len ++ ){ //枚举长度,可以等于n
for(int l = 0; l + len - 1 < n; l ++ ){ //枚举左端点
int r = l + len - 1; //右端点
for(int k = r + 1; k < n; k ++ ){
memcpy(w[depth], q, sizeof q);
int x, y;
//w中的值始终没变,所以不用担心赋值打乱原本序列顺序
for(x = r + 1, y = l; x <= k; x ++ , y ++ ) q[y] = w[depth][x]; //将选出的l~r片段到插入位置k之间的片段赋到l~r的位置
for(x = l; x <= r; x ++ , y ++ ) q[y] = w[depth][x]; //将l~r位置的值赋到k之后
if(dfs(depth + 1, max_depth)) return true;
memcpy(q, w[depth], sizeof q);
}
}
}
return false;
}
int main()
{
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) puts("5 or more");
else cout<<depth<<endl;
}
return 0;
}