工作分配——搜索与回溯
题目描述 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
B:J3
……
total=XXX
思路:
1.用数组f储存工作选择的方案;数组g存放最优的工作选择方案;数组p用于表示某项工作有没有被选择了
2.①选择p[i]=0的第i项工作
②判断效益是否高于max已记录的效益,若高于则更新g数组及max的值
2.①选择p[i]=0的第i项工作
②判断效益是否高于max已记录的效益,若高于则更新g数组及max的值
③计算完要清场(还原场景:把暂存效益减去,数组p[i]重新标记为0)
⒊搜索策略: 回溯法(深度优先搜索dfs)
⒊搜索策略: 回溯法(深度优先搜索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\n",64+i,gongzuo[i]);//第几个人做第几项工作 42 } 43 printf("total=%d\n",zhongjie);//输出最大效益 44 return 0; 45 }
我不怕千万人阻挡,只怕自己投降…