排書(IDA*)
阿新 • • 發佈:2020-12-28
給定n本書,編號為1-n。
在初始狀態下,書是任意排列的。
在每一次操作中,可以抽取其中連續的一段,再把這段插入到其他某個位置。
我們的目標狀態是把書按照1-n的順序依次排列。
求最少需要多少次操作。
輸入格式
第一行包含整數T,表示共有T組測試資料。
每組資料包含兩行,第一行為整數n,表示書的數量。
第二行為n個整數,表示1-n的一種任意排列。
同行數之間用空格隔開。
輸出格式
每組資料輸出一個最少操作次數。
如果最少操作次數大於或等於5次,則輸出”5 or more”。
每個結果佔一行。
資料範圍
1≤n≤15
輸入樣例:
3
6
1 3 4 6 2 5
5
5 4 3 2 1
10
6 8 5 3 4 7 2 9 1 10
輸出樣例:
2
3
5 or more
#include <iostream> #include <algorithm> #include <cstring> using namespace std; const int N = 15 ; int p[N]; int mc[5][N]; int T; int n ; int f()//估計函式 { int tol = 0; for(int i = 0; i+1 < n ; i++) { if(p[i+1] !=p[i] + 1)tol++; } return (tol +2) / 3; } bool dfs(int u , int depath)//當前需要的操作次數 總共能夠遍歷多少層 { if(u + f() > depath) return false; if(f() == 0) return true; for(int len = 1; len <= n ; len ++) { for(int l = 0 ; len + l - 1 < n ; l ++) { int r = len + l - 1; for(int k = r + 1; k < n ; k++) { memcpy(mc[u], p , sizeof p);//先copy下來 便於後面回溯 int y = l ; for(int x = r + 1 ; x <= k ; x ++,y ++)p[y] = mc[u][x];//用來置換替換後的位置 for(int x = l ; x <= r; x++ , y ++ )p[y] = mc[u][x];//後半段 if(dfs(u + 1, depath))return true; memcpy(p, mc[u] , sizeof p);//回溯 } } } return false; } int main() { cin >> T; while(T--) { cin >> n ; for(int i = 0 ; i < n ; i ++) cin >> p[i]; int depath = 0 ; while(depath < 5 && !dfs(0,depath)) ++depath; if(depath >= 5) puts("5 or more"); else cout << depath << endl; } return 0; }