工作分配——搜索与回溯

题目描述 Description

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

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

输入输出格式 Input/output

输入格式:

输出格式:
A:J5
B:J3
 ……
total=XXX
输入输出样例 Sample input/output
样例测试点#1
输入样例:
输出样例:
A:J5
B:J3
 ……
total=XXX
思路:
1.用数组f储存工作选择的方案;数组g存放最优的工作选择方案;数组p用于表示某项工作有没有被选择了
2.①选择p[i]=0的第i项工作
   ②判断效益是否高于max已记录的效益,若高于则更新g数组及max的值
   ③计算完要清场(还原场景:把暂存效益减去,数组p[i]重新标记为0)
⒊搜索策略: 回溯法(深度优先搜索dfs)
代码如下:
 1 #include<stdio.h>
 2 int fangan[6][6]={{0,0,0,0,0,0},{0,13,11,10,4,7},{0,13,10,10,8,5},{0,5,9,7,7,4},{0,15,12,10,11,5},{0,10,11,8,8,4}};//保存每个工作的效益
 3 int gongzuo[5];//最优的方案 
 4 int jilu[10];//暂存 
 5 int u[5]={0};//表示这个工作是否被选择了 
 6 int total=0;//最大的效益 
 7 int zhongjie=0;//中介,用来保存当前的效益 
 8 int search(int people,int xiaoyi)//第几个人、效益 
 9 {
10     int i,j;
11     for(i=1;i<=5;i++)//5个工作 
12     {
13         if(u[i]==0)//这个工作没被选过 
14         {
15             jilu[people]=i;//第几个人做什么事
16             u[i]=1;//这个工作被做了
17             xiaoyi+=fangan[people][i];//加上效益 
18             if(people<5)//没有满5个人 
19             {
20                 search(people+1,xiaoyi);//继续找                
21             } 
22             if(xiaoyi>zhongjie)//分配满了,保存之 
23             {
24                 zhongjie=xiaoyi;//如果效益大,保存起来 
25                 for(j=1;j<=5;j++)
26                 {
27                     gongzuo[j]=jilu[j];//保存工作方案 
28                 }
29             }
30             xiaoyi-=fangan[people][i];//退出这个循环,减掉这个人的效益(回溯)  
31             u[i]=0;//还原场景 
32         }        
33     }     
34 }
35 int main()
36 {
37     int i;
38     search(1,0);//从第一个人开始扫    
39     for(i=1;i<=5;i++)
40     {
41         printf("%c:J%d
",64+i,gongzuo[i]);//第几个人做第几项工作 
42     }
43     printf("total=%d
",zhongjie);//输出最大效益 
44     return 0;
45 }
原文地址:https://www.cnblogs.com/geek-007/p/4524578.html