首先说说IDS,就DFS限定一个层数上限maxd,如果在maxd范围内没有找到解,就增加maxd,继续搜索。

当访问到当前结点u时,估计还要搜索h(u)层,如果h(u)+当前层数d>maxd的时候就剪枝,这就是IDA*。

IDA*属于DFS,当状态空间某一层的结点数无穷大时,BFS失效,只能DFS。

相比BFS,它的空间占用少(不需要判重复),时间效率也不低。

注意:A*的关键在于选取估价函数h()。

----------------------------------分割线-------------------------------------------------------------

来说说 UVA11212 EditingaBook

缩小搜索空间的策略有

策略1:只剪切连续的数字片段。

策略2:剪切的片段头为a尾为b,要么粘贴到a-1的后面,要么粘贴到b+1前面。

策略3:不要破坏已经连续的片段。

但是策略1和策略2并能保证正解:如5 4 3 2 1 —》 3 2 5 4 1 —》 3 4 1 2 5 -》 1 2 3 4 5。

策略1,2出错主要是因为忽略了后效性,策略3是可以的,把连续的片段看成整体,拆开它一定是比不拆它的步数要少。

下面寻找估价函数

由于每次剪切最多更改3个数字的前继(或后继),所以统计前继不对的数字个数为n个那么只少还要搜n/3层。如果d+n/3>maxd即3*d+n>maxd就剪枝。

还有一个剪枝是:移动片段b1~b2到b2+1~c后面,相当于移动b2+1~c到b1~b2前面,所以只要枚举把片段往后移动就行了。

  1. //Rey
  2. #include<bits/stdc++.h>
  3.  
  4. const int maxn = ;
  5.  
  6. int n,a[maxn];
  7.  
  8. inline bool End()
  9. {
  10. for(int i = ; i < n; i++){
  11. if(a[i] <= a[i-]) return false;
  12. }
  13. return true;
  14. }
  15.  
  16. inline int h()
  17. {
  18. int cnt = ;
  19. for(int i = ; i < n; i++)
  20. if(a[i] != a[i-]+) cnt++;
  21. return cnt;
  22. }
  23.  
  24. int maxd;
  25. const int intsz = sizeof(int);
  26. const int asz = sizeof(a);
  27. bool dfs(int d)
  28. {
  29. if(*d + h() > *maxd) return false;
  30. if(End()) return true;
  31.  
  32. int old[maxn];//保存a
  33. memcpy(old,a,asz);
  34. int b[maxn];//剪切板
  35.  
  36. for(int i = ; i < n; i++) if( i == || old[i] != old[i-] + ) //策略3 选择尽量长的连续片段 剪切的起点
  37. for(int j = i; j < n; j++) { //终点 和 策略2不同选取片段可以不连续
  38. while(j+ < n && old[j+] == old[j] + )j++;//策略3
  39. memcpy(b,old+i,intsz*(j-i+));
  40. //剪切移动片段
  41. for(int k = j+;k < n;k++){//由于对称性,只要往后贴就行了
  42. while(k+ < n && old[k+] == old[k] + )k++;//策略3 不破坏
  43. memcpy(a+i,old+j+,intsz*(k-j));
  44. memcpy(a+i+k-j,b,intsz*(j-i+));
  45. if(dfs(d+))return true;
  46. //恢复
  47. memcpy(a,old,asz);
  48. }
  49. }
  50. return false;
  51. }
  52.  
  53. inline int solve()
  54. {
  55. if(End())return ;
  56. for(maxd = ; maxd < ;maxd++)
  57. if(dfs()) return maxd;
  58. return ;
  59. }
  60. int main()
  61. {
  62. //freopen("in.txt","r",stdin);
  63. int Cas = ;
  64. while(~scanf("%d",&n)&&n) {
  65. for(int i = ; i < n; i++)
  66. scanf("%d",a+i);
  67. int ans = solve();
  68. printf("Case %d: %d\n",++Cas,ans);
  69. }
  70. return ;
  71. }

UVA11212 EditingaBook ( IDA*搜索)的更多相关文章

  1. [BZOJ 1085] [SCOI2005] 骑士精神 [ IDA* 搜索 ]

    题目链接 : BZOJ 1085 题目分析 : 本题中可能的状态会有 (2^24) * 25 种状态,需要使用优秀的搜索方式和一些优化技巧. 我使用的是 IDA* 搜索,从小到大枚举步数,每次 DFS ...

  2. HDU 1560 IDA*搜索

    用N个串中找到最短的公共串(不要求连续,仅仅要相对位置一样就可以) 迭代加深搜索就可以 剪枝:当前的深度+最少还有加深的深度是否大于限制的长度,若是,则退回. #include "stdio ...

  3. UVA - 11212 Editing a Book (IDA*搜索)

    题目: 给出n(1<n<10)个数字组成的序列,每次操作可以选取一段连续的区间将这个区间之中的数字放到其他任意位置.问最少经过多少次操作可将序列变为1,2,3……n. 思路: 利用IDA* ...

  4. 八数码问题 IDA*搜索

    #include<iostream> #include<string> #include<cmath> #include<cstring> #inclu ...

  5. UVA - 11212 Editing a Book(IDA*算法+状态空间搜索)

    题意:通过剪切粘贴操作,将n个自然段组成的文章,排列成1,2,……,n.剪贴板只有一个,问需要完成多少次剪切粘贴操作可以使文章自然段有序排列. 分析: 1.IDA*搜索:maxn是dfs的层数上限,若 ...

  6. IDA调试android so的.init_array数组

    参考: http://www.itdadao.com/articles/c15a190757p0.html 一. 为什么要调试init_array init_array的用途 1. 一些全局变量的初始 ...

  7. 迭代,IDA*

    1.codevs1288 题意:对于一个分数a/b(a!=1),将它表示为1/x + 1/y + 1/z ……的形式,x,y,z……互不相同 多解取加数少的,加数相同时,取最小的分数最大的. 思路:经 ...

  8. codevs1288 埃及分数(IDA*)

    1288 埃及分数  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond     题目描述 Description 在古埃及,人们使用单位分数的和(形如1/a的 ...

  9. hdu 1667 The Rotation Game ( IDA* )

    题目大意: 给你一个“井”子状的board,对称的由24个方块组成,每个方块上有123三个数字中的一个.给你初始状态,共有八种变换方式,求字典序最小的最短的的变换路径使得,board中间的八个方块上数 ...

随机推荐

  1. Thinkphp5+plupload图片上传功能,支持实时预览图片。

    今天和大家分享一个国外的图片上传插件,这个插件支持分片上传大文件.其中著名的七牛云平台的jssdk就使用了puupload插件,可见这个插件还是相当牛叉的. 这个插件不仅仅支持图片上传,还支持大多数文 ...

  2. Linux/Unix中的命令提示符prompt

    用惯了DOS的伙计刚用Unix时最想干的事情就是想把Unix搞得像DOS一些, 其中的一条就是把Unix的提示符设置成$p$g那样的.下面就说一说做的方法. 不同的SHELL设置的方法不同,比较方便的 ...

  3. debian linux中文桌面系统安装

    一.基本系统安装 1 .安装光盘:可以到http://debian.cn99.com去下载ISO,我是之前从官方网站下载的.一只载第一张光盘即可.用NERO烧录成光碟. 2.将安装光盘放驱,并在BIO ...

  4. Codeforces Round #360 (Div. 1)A (二分图&dfs染色)

    题目链接:http://codeforces.com/problemset/problem/687/A 题意:给出一个n个点m条边的图,分别将每条边连接的两个点放到两个集合中,输出两个集合中的点,若不 ...

  5. codeforces786E ALT【倍增+最小割】

    方案二选一,显然是最小割,朴素的想法就是一排人点一排边点,分别向st连流量1的边,然后人点向路径上的边点连流量inf的边跑最大流 但是路径可能很长,这样边数就爆了,所以考虑倍增,然后倍增后大区间向小区 ...

  6. Codevs 1688 求逆序对(权值线段树)

    1688 求逆序对  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解  查看运行结果     题目描述 Description 给定一个序列a1,a2,…, ...

  7. [Xcode 实际操作]七、文件与数据-(8 )读取和解析Plist文件(属性列表文件)

    目录:[Swift]Xcode实际操作 本文将演示如何读取和解析Plist文件,即属性列表文件. 它是用来存储,串行化后的对象的文件. 在项目名称上点击鼠标右键,弹出右键菜单, 选择[New File ...

  8. crm项目整理概要

    一.开发背景 由于公司人员的增多,原来通过excel表格存取方式过于繁琐,而且对于公司人员的调配和绩效考核等不能做到精确处理,所以开发crm系统,开始开发只是针对销售人员和客户,后面陆续加上一些操作, ...

  9. Maven打包Spark程序Pom配置

    scala和java混合的spark程序之前使用其他配置始终有报找不到包的情况,尝试了一下如下配置可以打包成功.<build> <pluginManagement> <p ...

  10. python入门2(补发a)

    一.流程控制-while循环,结构如下: while 条件: 结果 如果条件是真,则直接执行结果,然后再次判断条件,直到条件是假,停止循环 那么我们如何终止循环呢? 1,改变循环条件 2,break ...