考察:IDA*+离散化ios
这估价函数本蒟蒻彻底没想到....数组
思路:ide
最少操做次数,若是用bfs须要存储数组.考虑一波IDA*,无需存储数组只须要回溯.可是估价函数很差想.参考了大佬的题解,原来须要离散化....将不一样的半径按大小映射为1~n之间的数字.目标就是让最终序列为1...n递增排序.能够发现,咱们每操做一次,就改变操做区间右端点与非操做区间左端点的大小关系.咱们能够发现最终序列a[i+1]-a[i] = 1.那么对于当前序列a[i+1]-a[i] != 1,res++.是否可行?函数
答案是不可行.对于5 4 3 2 1.按上面的预估函数返回结果是4,实际操做数是1.那么延伸一下abs(a[i+1]-a[i])!=1,res++.是否可行.答案是可行,但咱们须要将a[n+1]设置为n+1才行.不然5 4 3 2 1返回0.spa
这样的预估函数为何正确?对于a[l],a[l+1],若是它们之间的差不是1 or -1,那么就须要将前面的数换走,不然二者先后二者之差的绝对值不会改变.因此每个不为-1 or 1的差,至少须要1次翻转.排序
1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 const int N = 20; 6 int r[N],n,b[N],deep; 7 int h() 8 { 9 int res = 0; 10 for(int i=0;i<n;i++) 11 res+=(abs(r[i+1]-r[i])==1?0:1); 12 return res; 13 } 14 bool dfs(int depth,int pre) 15 { 16 int val = h(); 17 if(val+depth>deep) return 0; 18 if(!val) return 1; 19 for(int i=2;i<=n;i++) 20 { 21 if(i==pre) continue; 22 reverse(r,r+i); 23 if(dfs(depth+1,i)) return 1; 24 reverse(r,r+i); 25 } 26 return 0; 27 } 28 int main() 29 { 30 scanf("%d",&n); 31 for(int i=0;i<n;i++) scanf("%d",&r[i]); 32 memcpy(b,r,sizeof r); 33 sort(b,b+n); 34 for(int i=0;i<n;i++) 35 r[i] = lower_bound(b,b+n,r[i])-b+1; 36 r[n] = n+1; 37 while(!dfs(0,-1)) deep++; 38 printf("%d\n",deep); 39 return 0; 40 }
总结:string
IDA* h()函数常见操做:it
1.不在位置上的数,res++io
2.某次操做后,边界关系.class