第5章 搜索与回溯算法C++版一本通课件.ppt

第5章 搜索与回溯算法C++版一本通课件.ppt

  1. 1、本文档共48页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
算法设计:S1:产生5个数字的一个全排列; S2:检查是否符合“喜爱书表”的条件,如果符合就打印出来; S3:检查是否所有的排列都产生了,如果没有产生完,则返回S1; S4:结束。 int Search(i) { for (j=1;j<=5;j++) { if (第i个同学分给第j本书符合条件) { 记录第i个数 if (i==5) 打印一个解; else Search(i+1); 删去第i 个数 } } } 上述算法有可以改进的地方。比如产生了一个全排列12345,从表中可以看出,选第一本书即给张同学的书,1是不可能的,因为张只喜欢第3、4本书。这就是说,1××××一类的分法都不符合条件。由此想到,如果选定第一本书后,就立即检查一下是否符合条件,发现1是不符合的,后面的四个数字就不必选了,这样就减少了运算量。换句话说,第一个数字只在3、4中选择,这样就可以减少3/5的运算量。同理,选定了第一个数字后,也不应该把其他4个数字一次选定,而是选择了第二个数字后,就立即检查是否符合条件。例如,第一个数选3,第二个数选4后,立即检查,发现不符合条件,就应另选第二个数。这样就把34×××一类的分法在产生前就删去了。又减少了一部分运算量。 综上所述,改进后的算法应该是:在产生排列时,每增加一个数,就检查该数是否符合条件,不符合,就立刻换一个,符合条件后,再产生下一个数。因为从第I本书到第I+1本书的寻找过程是相同的,所以可以用回溯算法。算法设计如下: 【参考程序】 #include<cstdio> #include<iostream> #include<cstdlib> using namespace std; int book[6],c; bool flag[6],like[6][6]={{0,0,0,0,0,0},{0,0,0,1,1,0},{0,1,1,0,0,1}, {0,0,1,1,0,0},{0,0,0,0,1,0},{0,0,1,0,0,1}};; int search(int); int print(); int main() { for (int i=1;i<=5;i++) flag[i]=1; search(1); //从第1个开始选书,递归。 } int search(int i) //递归函数 { for (int j=1;j<=5; j++) //每个人都有5本书可选 if (flag[j]&&like[i][j]) //满足分书的条件 { flag[j]=0; //把被选中的书放入集合flag中,避免重复被选 book[i]=j; //保存第i个人选中的第j本书 if (i==5) print(); //i=5时,所有的人都分到书,输出结果 else search(i+1); //i<5时,继续递归分书 flag[j]=1; //回溯:把选中的书放回,产生其他分书的方案 book[i]=0; } } int print() { c++; //方案数累加1 cout <<"answer " <<c <<":\n"; for (int i=1;i<=5;i++) cout <<i <<": " <<char(64+book[i]) <<endl; //输出分书的方案 } 输出结果: answer 1 1: C 2: A 3: B 4: D 5: E 【例8】

文档评论(0)

精品文档 + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档