题意:给n个不同大小的盒子,小盒子可以叠在大盒子上,每次可向左或右相邻的位置移动该位置最顶的盒子,求使所有盒子从小到大有序所需最少移动次数。
思路:从终态bfs爆搜预处理出到达所有状态需要的步数。
#pragma comment(linker, "/STACK:102400000,102400000")
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <queue>
#include <map>
#include <vector>
#include <algorithm>
//#include <conio.h>
#include <iostream>
using namespace std;
#define rd(x) scanf("%d",&x)
#define rd2(x,y) scanf("%d%d",&x,&y)
#define ll long long int
#define maxn 205
#define mod 1000000007
#define pii pair<int,int>
int v7[8][8][8][8][8][8][8];
int v6[8][8][8][8][8][8];
int v5[8][8][8][8][8];
int v4[8][8][8][8];
int v3[8][8][8];
int v2[8][8];
bool check(int a[],int n,int step){
if(n==2){
if(v2[a[1]][a[2]]!=-1) return 0;
else {
v2[a[1]][a[2]]=step;return 1;
}
}
else if(n==3){
if(v3[a[1]][a[2]][a[3]]!=-1) return 0;
else {
v3[a[1]][a[2]][a[3]]=step;return 1;
}
}
else if(n==4){
if(v4[a[1]][a[2]][a[3]][a[4]]!=-1) return 0;
else {
v4[a[1]][a[2]][a[3]][a[4]]=step;return 1;
}
}
else if(n==5){
if(v5[a[1]][a[2]][a[3]][a[4]][a[5]]!=-1) return 0;
else {
v5[a[1]][a[2]][a[3]][a[4]][a[5]]=step;return 1;
}
}
else if(n==6){
if(v6[a[1]][a[2]][a[3]][a[4]][a[5]][a[6]]!=-1) return 0;
else {
v6[a[1]][a[2]][a[3]][a[4]][a[5]][a[6]]=step;return 1;
}
}
else if(n==7){
if(v7[a[1]][a[2]][a[3]][a[4]][a[5]][a[6]][a[7]]!=-1) return 0;
else {
v7[a[1]][a[2]][a[3]][a[4]][a[5]][a[6]][a[7]]=step;return 1;
}
}
}
struct node{
int a[10];
int step;
};
void solve(int n){
int a[10];
for(int i=1;i<=n;i++) a[i]=i;
check(a,n,0);
queue<node> qq;
node s;s.step=0;
for(int i=1;i<=n;i++) s.a[i]=i;
qq.push(s);
while(!qq.empty()){
s=qq.front();qq.pop();
for(int i=1;i<=n;i++){//第i个点向左或右移
// int kk=s.a[i];
int l=1;
int r=1;
for(int j=1;j<i;j++){
if(s.a[j]==s.a[i]-1) l=0;//左有更小的
if(s.a[j]==s.a[i]+1) r=0;//右有更小的
if(s.a[j]==s.a[i]) l=r=0;//该点上方有更小的
}
if(s.a[i]-1<1) l=0;
if(s.a[i]+1>n) r=0;
if(l){
s.a[i]=s.a[i]-1;s.step+=1;
if(check(s.a,n,s.step)) qq.push(s);
s.a[i]+=1;s.step-=1;
}
if(r){
s.a[i]+=1;s.step+=1;
if(check(s.a,n,s.step)) qq.push(s);
s.a[i]-=1;s.step-=1;
}
}
}
}
void init(){
memset(v7,-1,sizeof(v7));
memset(v6,-1,sizeof(v6));
memset(v5,-1,sizeof(v5));
memset(v4,-1,sizeof(v4));
memset(v3,-1,sizeof(v3));
memset(v2,-1,sizeof(v2));
for(int i=2;i<=7;i++){
solve(i);
}
}
int h[10005],t,n,a[10],b[10];
int main()
{
rd(t);
init();
while(t--){
rd(n);
for(int i=1;i<=n;i++){
rd(b[i]);h[b[i]]=i;
}
sort(b+1,b+1+n);
for(int i=1;i<=n;i++) a[i]=h[b[i]];
if(n==1) printf("0\n");
else if(n==2) printf("%d\n",v2[a[1]][a[2]]);
else if(n==3) printf("%d\n",v3[a[1]][a[2]][a[3]]);
else if(n==4) printf("%d\n",v4[a[1]][a[2]][a[3]][a[4]]);
else if(n==5) printf("%d\n",v5[a[1]][a[2]][a[3]][a[4]][a[5]]);
else if(n==6) printf("%d\n",v6[a[1]][a[2]][a[3]][a[4]][a[5]][a[6]]);
else if(n==7) printf("%d\n",v7[a[1]][a[2]][a[3]][a[4]][a[5]][a[6]][a[7]]);
}
return 0;
}