本章聚集了一些做了的迭代启发式搜索的题目

为什么只打了迭代启发式搜索?

因为它很好打,有些类似迭代的时候加的最优化剪枝

[因为这个最优化剪枝其实就是你算的估价函数了...]

BZOJ 1085 骑士精神

比较经典的一题,特别是题目中还说了在15步内走完...看上去就是迭代的样子

估价函数->指棋盘上不符合规定的骑士数目...每次移动最多让一名骑士回到自己的位置,由此来剪枝

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4.  
  5. using namespace std;
  6.  
  7. int maxd,sx,sy;
  8. char ch[][];
  9. int x[]={,,-,-,,,-,-};
  10. int y[]={,-,,-,,-,,-};
  11. int ans[][]={{,,,,},{,,,,},{,,,,},{,,,,},{,,,,}};
  12.  
  13. struct Node{
  14. int a[][];
  15. int illegal(){
  16. int cnt=;
  17. for(int i=;i<;i++)
  18. for(int j=;j<;j++)
  19. if(a[i][j]!=ans[i][j]) cnt++;
  20. return cnt;
  21. }
  22. };
  23.  
  24. inline bool judge(int a[][]){
  25. for(int i=;i<;i++)
  26. for(int j=;j<;j++)
  27. if(a[i][j]!=ans[i][j]) return false;
  28. return true;
  29. }
  30.  
  31. inline bool inmap(int x,int y){
  32. if(x>= || x< || y>= || y<) return false;
  33. return true;
  34. }
  35.  
  36. bool dfs(int level,Node s,int bx,int by){
  37. if(!level){
  38. if(judge(s.a)) return true;
  39. return false;
  40. }
  41. int newx,newy;
  42. for(int i=;i<;i++){
  43. newx=bx+x[i],newy=by+y[i];
  44. if(inmap(newx,newy)){
  45. swap(s.a[bx][by],s.a[newx][newy]);
  46. if(s.illegal()<=level)
  47. if(dfs(level-,s,newx,newy)) return true;
  48. swap(s.a[bx][by],s.a[newx][newy]);
  49. }
  50. }
  51. return false;
  52. }
  53.  
  54. int main(){
  55. #ifndef ONLINE_JUDGE
  56. freopen("1085.in","r",stdin);
  57. freopen("1085.out","w",stdout);
  58. #endif
  59. int kase;
  60. Node s;
  61. scanf("%d",&kase);
  62. while(kase--){
  63. for(int i=;i<;i++){
  64. scanf("%s",ch[i]);
  65. for(int j=;j<;j++)
  66. if(ch[i][j]=='*') s.a[i][j]=,sx=i,sy=j;
  67. else if(ch[i][j]=='') s.a[i][j]=;
  68. else s.a[i][j]=;
  69. }
  70. if(!s.illegal()) {puts("");continue;}
  71. for(maxd=;maxd<=;maxd++)
  72. if(dfs(maxd,s,sx,sy)) break;
  73. if(maxd<=)
  74. printf("%d\n",maxd);
  75. else
  76. puts("-1");
  77. }
  78. return ;
  79. }

codevs1288 埃及分数

强行把从某个状态之后的最小值看做估价函数也是可以的...紫书例题

不过有一些坑点,看codevs题解的第一篇吧(...我写的)。

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4.  
  5. using namespace std;
  6.  
  7. typedef long long ll;
  8.  
  9. const int maxn=;
  10. const int INF=0x7f7f7f7f;
  11.  
  12. int a,b,d;
  13. ll res[maxn],rec[maxn];
  14.  
  15. ll gcd(ll a,ll b){
  16. ll t;
  17. while(b)
  18. t=b,b=a%b,a=t;
  19. return a;
  20. }
  21.  
  22. inline bool better(ll a[]){
  23. if(a[]>=res[]) return false;
  24. else return true;
  25. for(int i=;i<=d;i++)
  26. if(a[i]<res[i]) return true;
  27. else if(a[i]>res[i]) return false;
  28. return false;
  29. }
  30.  
  31. bool dfs(int level,ll last,ll aa,ll bb){
  32. if(level==){
  33. if(bb%aa) return false;
  34. rec[]=bb/aa;
  35. if(better(rec))
  36. for(int i=;i<=d;i++) res[i]=rec[i];
  37. return true;
  38. }
  39. bool ok=false;
  40. last=max(last+,(bb/aa)+!(bb%aa==));
  41. for(int i=last;;i++){
  42. if(aa*i>=bb*level) break;
  43. ll b1=bb*i,a1=aa*i-bb,Gcd;
  44. Gcd=gcd(a1,b1);
  45. a1/=Gcd,b1/=Gcd;rec[level]=i;
  46. if(dfs(level-,i,a1,b1)) ok=true;
  47. }
  48. return ok;
  49. }
  50.  
  51. int main(){
  52. scanf("%d%d",&a,&b);
  53. memset(res,0x7f,sizeof(res));
  54. for(d=;!dfs(d,,a,b);d++);
  55. for(int i=d;i>=;i--)
  56. printf("%lld ",res[i]);
  57.  
  58. return ;
  59. }

codevs2495 水叮当的舞步

这题估价函数居然就是一个颜色?...我其实有想过什么连通块个数的估价然而没有什么用...

其实这题关键还是在于给左上角染色的过程,每次给变色的地方染1,变色的周围染2,然后每次的颜色只要扩展2中相同的就好...比每次dfs快上很多的样子...

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4.  
  5. using namespace std;
  6.  
  7. int maxd,n;
  8. int mp[][],mark[][];
  9. int xx[]={,-,,};
  10. int yy[]={,,-,};
  11. bool used[];
  12. bool ans;
  13.  
  14. int get(){
  15. int cnt=;
  16. memset(used,,sizeof(used));
  17. for(int i=;i<=n;i++)
  18. for(int j=;j<=n;j++)
  19. if(!used[mp[i][j]] && mark[i][j]!=)
  20. used[mp[i][j]]=,cnt++;
  21. return cnt;
  22. }
  23.  
  24. void dfs(int a,int b,int x){
  25. mark[a][b]=;
  26. for(int i=;i<;i++){
  27. int nowx=a+xx[i],nowy=b+yy[i];
  28. if(nowx<||nowy<||nowx>n||nowy>n||mark[nowx][nowy]==) continue;
  29. mark[nowx][nowy]=;
  30. if(mp[nowx][nowy]==x)dfs(nowx,nowy,x);
  31. }
  32. }
  33.  
  34. int fill(int x){
  35. int cnt=;
  36. for(int i=;i<=n;i++)
  37. for(int j=;j<=n;j++)
  38. if(mark[i][j]==&&mp[i][j]==x)
  39. cnt++,dfs(i,j,x);
  40. return cnt;
  41. }
  42.  
  43. bool search(int level){
  44. int v=get();
  45. if(!v) return true;
  46. if(v>level) return false;
  47. int temp[][];
  48. for(int i=;i<=;i++){
  49. memcpy(temp,mark,sizeof(mark));
  50. if(fill(i)) if(search(level-)) return true;
  51. memcpy(mark,temp,sizeof(mark));
  52. }
  53. return false;
  54. }
  55.  
  56. int main(){
  57.  
  58. while(~scanf("%d",&n)){
  59. if(!n) break;
  60. memset(mark,,sizeof(mark));
  61. ans=;
  62. for(int i=;i<=n;i++)
  63. for(int j=;j<=n;j++)
  64. scanf("%d",&mp[i][j]);
  65. dfs(,,mp[][]);
  66. for(maxd=;!search(maxd);maxd++);
  67. printf("%d\n",maxd);
  68. }
  69. return ;
  70. }

UVa11212 编辑书稿

估价函数比较精妙,每次最多让三个元素的后继正确。

为什么是后继呢?因为这个操作的本质就是改变后继...

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<cstdlib>
  4. #include<algorithm>
  5.  
  6. using namespace std;
  7.  
  8. const int maxn=;
  9.  
  10. struct Node{
  11. int v[maxn];
  12. };
  13.  
  14. int n,maxd;
  15.  
  16. inline int get_h(int a[]){
  17. int cnt=;
  18. for(int i=;i<n;i++)
  19. if(a[i+]!=a[i]+) cnt++;
  20. return cnt;
  21. }
  22.  
  23. void move(Node &Start,Node &Next,int I,int J,int K){
  24. for(int i=;i<=K-J-;i++)
  25. Next.v[i+I]=Start.v[J++i];
  26. for(int i=;i<=J-I;i++)
  27. Next.v[K-J+I+i]=Start.v[i+I];
  28. }
  29.  
  30. bool dfs(int level,Node s){
  31. if(get_h(s.v)>*level) return false;
  32. if(get_h(s.v)==) return true;
  33.  
  34. Node next;
  35. for(int i=;i<=n;i++)
  36. for(int j=i;j<=n;j++)
  37. for(int k=j+;k<=n;k++){
  38. memcpy(next.v,s.v,sizeof(s.v));
  39. move(s,next,i,j,k);
  40. if(dfs(level-,next)) return true;
  41. }
  42. return false;
  43. }
  44.  
  45. int main(){
  46. #ifndef ONLINE_JUDGE
  47. freopen("11212.in","r",stdin);
  48. freopen("11212.out","w",stdout);
  49. #endif
  50.  
  51. int kase=;
  52. Node a0;
  53.  
  54. while(~scanf("%d",&n)){
  55. if(!n) break;
  56. for(int i=;i<=n;i++)
  57. scanf("%d",&a0.v[i]);
  58. if(!get_h(a0.v)){
  59. printf("Case %d: 0\n",++kase);
  60. continue;
  61. }
  62.  
  63. for(maxd=;!dfs(maxd,a0);maxd++);
  64. printf("Case %d: %d\n",++kase,maxd);
  65. }
  66.  
  67. return ;
  68. }

迭代启发式搜索 IDA*的更多相关文章

  1. 【2020-8-21】【数字游戏】【启发式搜索IDA*】

    有这么一个游戏: 写出一个1-N的排列a[i],然后每次将相邻两个数相加,构成新的序列,再对新序列进行这样的操作,显然每次构成的序列都比上一次的序列长度少1,直到只剩下一个数字位置.下面是一个例子: ...

  2. 【题解】AcWing 193. 算乘方的牛

    原题链接 题目描述 约翰的奶牛希望能够非常快速地计算一个数字的整数幂P(1 <= P <= 20,000)是多少,这需要你的帮助. 在它们计算得到最终结果的过程中只能保留两个工作变量用于中 ...

  3. 【Uva 12558】 Egyptian Fractions (HARD version) (迭代加深搜,IDA*)

    IDA* 就是iterative deepening(迭代深搜)+A*(启发式搜索) 启发式搜索就是设计估价函数进行的搜索(可以减很多枝哦~) 这题... 理论上可以回溯,但是解答树非常恐怖,深度没有 ...

  4. 小结:A* & IDA* & 迭代深搜

    概要: 在dfs中,如果答案的深度很小但是却很宽,而且bfs还不一定好做的情况下,我们就综合bfs的优点,结合dfs的思想,进行有限制的dfs.在这里A*.IDA*和迭代深搜都是对dfs的优化,因此放 ...

  5. 迭代,IDA*

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

  6. 埃及分数 迭代加深搜索 IDA*

    迭代加深搜索 IDA* 首先枚举当前选择的分数个数上限maxd,进行迭代加深 之后进行估价,假设当前分数之和为a,目标分数为b,当前考虑分数为1/c,那么如果1/c×(maxd - d)< a ...

  7. 迭代加深 A* IDA* 初探

    并没有有用的东西, 只是用来水的. 今天看搜索,想起来了A*和IDA* 看A*去了.... 啥玩意啊这是,他们代码为啥这么长??.... 看完了,...代码怎么写啊?? .....算了,直接看题吧 找 ...

  8. UVA 11212 Editing a Book [迭代加深搜索IDA*]

    11212 Editing a Book You have n equal-length paragraphs numbered 1 to n. Now you want to arrange the ...

  9. BZOJ1085: [SCOI2005]骑士精神 [迭代加深搜索 IDA*]

    1085: [SCOI2005]骑士精神 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1800  Solved: 984[Submit][Statu ...

随机推荐

  1. EasyUI datagrid checkbox数据设定与取值(转自http://blog.csdn.net/baronyang/article/dnetails/9323463,感谢分享,谢谢)

    这一篇将会说明两种使用 jQuery EasyUI DataGrid 的 Checkbox 设定方式,以及在既有数据下将 checked 为 true 的该笔数据列的 Checkbox 设定为 Che ...

  2. 别不拿里程碑当石头---------IT项目管理之项目计划(转)

    如果说做项目不需要计划,恐怕没人会认同.是否每个项目计划都起到了作用呢?却不尽然.知道要做计划,但不知道为什么做计划,如何做计划的还是大有人在.所以很多计划沦为依样画葫芦,成了摆设. IT项目计划的用 ...

  3. ThinkPHP之中getlist方法实现数据搜索功能

    自己在ThinkPHP之中的model之中书写getlist方法,其实所谓的搜索功能无非就是数据库查询之中用到的like  %string%,或者其他的 字段名=特定值,这些sql语句拼接在and语句 ...

  4. C# 平时碰见的问题【5】

    vs按F5启动调试,项目不会编译的解决办法 工具 -> 选项 -> 项目和解决方案 -> 运行时, 当项目过期(下拉框) -> 不要选[从不生成] 附英文版的:

  5. 5.html5中的路径表示

    路径在html中的作用主要是进行外部资源的引入,如css文件,js文件,媒体文件等. 而路径本身有分为相对路径和绝对路径.所谓相对路径,就是相对于链接页面而言的另一个页面的路径.而绝对路径,就是直接从 ...

  6. python 常用函数、内置函数清单

    文章内容摘自:http://www.cnblogs.com/vamei 1.type() 查询变量的类型 例: >>> a = 10>>> print a10> ...

  7. 几条sql语句

    1.行.列转换 --行转列 ),科目 ),分数 int) ) ) ) ) ) ) ) ) ) --方法1 select 姓名, end) as 语文, end) as 数学, end) as 物理 f ...

  8. rails的字符编码

    想练练手,随意的写了个登陆页面,简单的只有几行. <%= form_tag('login_check') do -%><%= text_field_tag 'user_name', ...

  9. .NET开源工作流RoadFlow-系统布署及注意事项

    非常感谢您在百忙之中抽空来了解RoadFlow,下面我们说一下如果在自己本地搭建环境吧. 1.环境要求 数据库:sqlserver2005以上版本.服务器:IIS6.0以上,或iisexpress.d ...

  10. 软件工程个人作业4(课堂练习&&课堂作业)

    题目:返回一个整数数组中最大子数组的和. 要求:1.输入一个整型数组,数组里有正书和负数. 2.数组中连续的一个或者多个整数组,每个子数组都有一个和. 3.求所有子数组的和的最大值.要求时间复杂度为0 ...