①IDA*搭配迭代加深,限制搜索层数depth
②估价函数用来判断该点到答案的理想步数(估价<=真实),如果已经走的步数+后续理想步数已经超过depth就不再往下搜索
③当前层数+估价函数>depth时可以剪枝
排书
题意:1~n乱序排放,每次操作可以移动连续的一段,求排好序的最少操作次数
思路:
//判断有多少个后继是不正确的,每一步最多修改三个后继
int h(int w[]){
int tot=0;
for(int i=1;i<n;i++)
if(w[i+1]!=w[i]+1)
tot++;
return (tot+2)/3;
}
bool check(int w[]){
for(int i=1;i<=n;i++){
if(w[i]!=i) return false;
}
return true;
}
//第u次操作
bool dfs(int u,int w[],int depth){
if(u+h(w)>depth) return false;
if(check(w)) return true;
for(int len=1;len<=n;len++){
for(int i=1;i+len-1<=n;i++){
int j=i+len-1;
//将[i,j]移到[k+1~]
for(int k=j+1;k<=n;k++){
int op[N];
int pos=1;
for(int z=1;z<i;z++) op[pos++]=w[z];
for(int z=j+1;z<=k;z++) op[pos++]=w[z];
for(int z=i;z<=j;z++) op[pos++]=w[z];
for(int z=k+1;z<=n;z++) op[pos++]=w[z];
if(dfs(u+1,op,depth)) return true;
}
}
}
return false;
}
int main(){
int t;cin>>t;
while(t--){
cin>>n;
for(int i=1;i<=n;i++){
cin>>w[i];
}
int depth=0;
while(!dfs(0,w,depth)){
depth++;
if(depth>=5) break;
}
if(depth>=5) cout<<"5 or more"<<endl;
else cout<<depth<<endl;
}
}