算法实验4《回溯法》

举报
用户已注销 发表于 2021/11/19 05:32:56 2021/11/19
【摘要】 1. 编写一个简单的程序,解决8皇后问题。 #include<iostream>using namespace std; bool backtrack(int list[8], int t){ if (t >= 8)return true; for (int i = 0; i < 8; i++) { li...

1. 编写一个简单的程序,解决8皇后问题。


  
  1. #include<iostream>
  2. using namespace std;
  3. bool backtrack(int list[8], int t)
  4. {
  5. if (t >= 8)return true;
  6. for (int i = 0; i < 8; i++)
  7. {
  8. list[t] = i;
  9. bool place = true;
  10. for (int j = 0; j < t; j++)if (list[j] == i || j-t==list[j]-i || j-t==i-list[j])place = false;
  11. if (place && backtrack(list, t+1))return true;
  12. continue;
  13. }
  14. return false;
  15. }
  16. int main()
  17. {
  18. int list[8];
  19. for (int i = 0; i < 8; i++)list[i] = 0;
  20. backtrack(list, 0);
  21. for (int i = 0; i < 8; i++)cout << list[i] << " ";
  22. system("pause>nul");
  23. return 0;
  24. }

2. 批处理作业调度问题
[问题描述]给定n个作业的集合J=(J1, J2, … , Jn)。每一个作业Ji都有两项任务需要分别在2台机器上完成。每一个作业必须先由机器1处理,然后再由机器2处理。作业Ji需要机器j的处理时间为tji,i=1,2, … ,n; j=1,2。
对于一个确定的作业调度,设Fji是作业i在机器j上完成处理的时间。则所有作业在机器2上完成处理的时间和成为该作业调度的完成时间和。 
批处理作业调度问题要求对于给定的n个作业,制定一个最佳的作业调度方案,使其完成时间和达到最小。 
要求输入: 

1)作业数 2)每个作业完成时间表: 

作业完成时间

机器1

机器2

作业1

2

1

作业2

3

1

作业3

2

要求输出: 1)最佳完成时间 2)最佳调度方案 
提示:算法复杂度为O(n!),建议在测试的时候n值不要太大,可以考虑不要超过12。


  
  1. #include<iostream>
  2. using namespace std;
  3. void backtrack(int *t1, int *t2, int *list1, int *list2, int *list, int &sumTime, int &time, int t, int n)
  4. {
  5. if (t >= n)
  6. {
  7. if (sumTime > time)sumTime = time;
  8. return;
  9. }
  10. for (int i = 0; i < n; i++) //选择1个作业
  11. {
  12. bool place = true;
  13. for (int j = 0; j < t; j++)if (list[j] == i)place = false; //判断这个作业是否可选
  14. if (!place)continue;
  15. list[t] = i;
  16. if (t)t1[t] = t1[t - 1];
  17. else t1[t] = 0;
  18. t1[t] += list1[i];
  19. if (t)t2[t] = (t1[t]>t2[t - 1]) ? t1[t] : t2[t - 1]; //这3行计算t2[i]
  20. else t2[t] = t1[t];
  21. t2[t] += list2[i];
  22. time += t2[t];
  23. if (time <= sumTime)backtrack(t1, t2, list1, list2, list, sumTime, time, t + 1, n);
  24. time -= t2[t];
  25. }
  26. }
  27. int main()
  28. {
  29. int n;
  30. cin >> n;
  31. int *list1 = new int[n]; //作业在机器1上运行的时间t11-t1n
  32. int *list2 = new int[n]; //作业在机器2上运行的时间t21-t2n
  33. int *t1 = new int[n]; //作业在机器1上完成的时间F11-F1n
  34. int *t2 = new int[n]; //作业在机器2上完成的时间F21-F2n
  35. int sumTime = 0; //总时间上界
  36. for (int i = 0; i < n; i++)
  37. {
  38. cin >> list1[i] >> list2[i];
  39. sumTime += (list1[i] + list2[i])*(i + 1);
  40. }
  41. int *list = new int[n]; //记录作业运行的顺序
  42. int time = 0; //总时间
  43. backtrack(t1, t2, list1, list2, list, sumTime, time, 0, n);
  44. cout << sumTime << endl;
  45. system("pause>nul");
  46. return 0;
  47. }


3. 数字全排列问题
任意给出从1到N的N个连续的自然数,求出这N个自然数的各种全排列。如N=3时,共有以下6种排列方式:123,132,213,231,312,321。
注意:数字不能重复,N由键盘输入(N<=9)。 


  
  1. #include<iostream>
  2. using namespace std;
  3. void backtrack(int n,int t,int *list)
  4. {
  5. if (t >= n)
  6. {
  7. for (int i = 0; i < n; i++)cout << list[i]+1 << " ";
  8. cout << endl;
  9. }
  10. for (int i = 0; i < n; i++)
  11. {
  12. bool flag = true;
  13. for (int j = 0; j < t; j++)if (list[j] == i)flag = false;
  14. if (flag)
  15. {
  16. list[t] = i;
  17. backtrack(n, t + 1, list);
  18. }
  19. }
  20. }
  21. int main()
  22. {
  23. int n;
  24. cin >> n;
  25. int list[9];
  26. backtrack(n, 0, list);
  27. system("pause>nul");
  28. return 0;
  29. }

文章来源: blog.csdn.net,作者:csuzhucong,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/nameofcsdn/article/details/78868638

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。