回溯与搜索 三 最高效益 选书

简介: 回溯与搜索 三 最高效益 选书

最高效益

设有A,B,C,D,E五人从事J1,J2,J3,J4,J5五项工作,每人只能从事一项,他们的效益如下。

每人选择五项工作中的一项,在各种选择的组合中,找到效益最高的的一种组合输出。

【算法分析】

⒈用数组f储存工作选择的方案;数组g存放最优的工作选择方案;数组p用于表示某项工作有没有被选择了。

⒉(1)选择p(i)=0的第i项工作;

  (2)判断效益是否高于max已记录的效益,若高于则更新g数组及max的值。

⒊搜索策略: 回溯法(深度优先搜索dfs)。

1. #include<iostream>
2. #include<cstdio>
3. #include<iomanip>
4. using namespace std;
5. int data[6][6]={{0,0,0,0,0,0},{0,13,11,10,4,7},
6.    {0,13,10,10,8,5},{0,5,9,7,7,4},
7.    {0,15,12,10,11,5},{0,10,11,8,8,4}};
8. int maxl=0,g[10],f[10];
9. bool p[6]={0};
10. int go(int step,int t)// step是第几个人,t是之前已得的效益
11. {
12.   for(int i=1;i<=5;i++){
13.     if(!p[i]){
14.       f[step]=i;
15.       p[i]=1;
16.       t+=data[step][i];
17.       if(step<5) go(step+1,t);
18.       else if(t>maxl){//保存最优效益下的工作选择方案
19.         maxl=t;
20.         for(int j=1;j<=5;j++) g[i]=f[i];
21.       }
22.       t-=data[step][i];//回溯上一步 
23.       p[i]=0;
24.     }   
25.   }
26. }
27. int main()
28. {
29.   go(1,0);
30.   for(int i=1;i<=5;i++)
31.     cout<<char(64+i)<<":J"<<g[i]<<setw(3);
32.   cout<<endl;
33.   cout<<"supply:"<<maxl<<endl;  
34.   return 0;
35.  }

选书

      学校放寒假时,信息学竞赛辅导老师有A,B,C,D,E五本书,要分给参加培训的张、王、刘、孙、李五位同学,每人只能选一本书。老师事先让每个人将自己喜欢的书填写在如下的表格中。然后根据他们填写的表来分配书本,希望设计一个程序帮助老师求出所有可能的分配方案,使每个学生都满意。

【算法分析】

      可用穷举法,先不考虑“每人都满意” 这一条件,这样只剩“每人选一本且只能选一本”这一条件。在这个条件下,可行解就是五本书的所有全排列,一共有5!=120种。然后在120种可行解中一一删去不符合“每人都满意”的解,留下的就是本题的解答。

      为了编程方便,设1,2,3,4,5分别表示这五本书。这五个数的一种全排列就是五本书的一种分发。例如54321就表示第5本书(即E)分给张,第4本书(即D)分给王,……,第1本书(即A)分给李。“喜爱书表”可以用二维数组来表示,1表示喜爱,0表示不喜爱。

算法设计:

S1:产生5个数字的一个全排列;

S2:检查是否符合“喜爱书表”的条件,如果符合就打印出来;

S3:检查是否所有的排列都产生了,如果没有产生完,则返回S1;

S4:结束。

改进算法:

在产生排列时,每增加一个数,就检查该数是否符合条件,不符合,就立刻换一个,符合条件后,再产生下一个数。因为从第I本书到第I+1本书的寻找过程是相同的,所以可以用回溯算法。算法设计如下:

1. int search(i)
2. {
3.  for(j=1;j<=5;j++){
4.    if(第i个同学分到第j本书符合条件){
5.      记录第i个数;
6.      if(i==5) 打印一个解;
7.      else search(i+1);
8.      删去第i个数; 
9.    } 
10.   }
11.  }
1. #include<iostream>
2. #include<cstdio>
3. #include<iomanip>
4. using namespace std;
5. int book[6],c=0;
6. bool flag[6];
7. bool like[6][6]={{0,0,0,0,0,0},{0,0,0,1,1,0},{0,1,1,0,0,1},
8.                 {0,0,1,1,0,0},{0,0,0,0,1,0},{0,0,1,0,0,1}};
9. void print()
10. {
11.   c++;
12.   cout<<"answer "<<c<<endl;
13.   for(int i=1;i<=5;i++) cout<<i<<":"<<char(64+book[i]) <<endl;  
14. }
15. int search(int i)
16. {
17.   for(int j=1;j<=5;j++){
18.     if((!flag[j])&&like[i][j]){
19.       flag[j]=1;
20.       book[i]=j;
21.       if(i==5) print();
22.       else search(i+1);
23.       flag[j]=0;
24.       book[i]=0;
25.     }   
26.   }
27. }
28. int main()
29. {
30.   search(1); 
31.   return 0;
32.  }

 

相关文章
|
4月前
|
算法
【算法】递归、搜索与回溯——简介
【算法】递归、搜索与回溯——简介
|
7月前
|
算法
【算法系列篇】递归、搜索和回溯(四)
【算法系列篇】递归、搜索和回溯(四)
|
7月前
深度优化搜索,字典树
深度优化搜索,字典树
71 0
|
7月前
|
算法
【算法系列篇】递归、搜索和回溯(三)
【算法系列篇】递归、搜索和回溯(三)
|
7月前
|
算法
【算法系列篇】递归、搜索和回溯(二)
【算法系列篇】递归、搜索和回溯(二)
|
7月前
|
算法
【算法系列篇】递归、搜索与回溯(一)
【算法系列篇】递归、搜索与回溯(一)
【算法提高——第二讲】搜索(2)
【算法提高——第二讲】搜索(2)
【算法提高——第二讲】搜索(2)
【算法提高——第二讲】搜索(1)
【算法提高——第二讲】搜索(1)
【算法提高——第二讲】搜索(1)
【算法提高——第二讲】搜索(3)
【算法提高——第二讲】搜索(3)
【算法提高——第二讲】搜索(3)