例5.6 设有A、B、C、D、E五人从事J1、J2、J3、J4、J5五项工作,每人只能从事一项,他们的效益如图下图所示。
J1 | J2 | J3 | J4 | J5 | |
---|---|---|---|---|---|
A | 13 | 11 | 10 | 4 | 7 |
B | 13 | 10 | 10 | 8 | 5 |
C | 5 | 9 | 7 | 7 | 4 |
D | 15 | 12 | 10 | 11 | 5 |
E | 10 | 11 | 8 | 8 | 4 |
每人选择五项工作中的一项,在各种选择的组合中,找到效益最高的一种组合输出。
【算法分析】
1.用数组f存储搜索中工作选择的方案;使用key存储最优解;数组p用于表示某项工作有没有被选择了。
2.(1)选择p(i)=0的第i项工作;
(2)判断效益是否高于max已记录的效益,若高于则更新max的值。
3.搜索策略:回溯法(深度优先搜索dfs)
【参考程序】
//每人选择五项工作中的一项,在各种选择的组合中,
//找到效益最高的一种组合输出。
#include <bits/stdc++.h>
using namespace std;
//1.初始化变量
int a[6]={0,13,11,10,4,7};
int b[6]={0,13,10,10,8,5};
int c[6]={0,5,9,7,7,4};
int d[6]={0,15,12,10,11,5};
int e[6]={0,10,11,8,8,4};
int tot=1;//记录方案数量
int maxn=0;
int key;//记录最大效益方案
bool p[6];
int f[10001][6];//保存每种方案
void search(int );//声明深搜函数
void solve();
int main(){
search(1);//从第一个人开始搜索
for(int i=1;i<=5;i++){
//输出每个人对应的工作
cout<<char(64+i)<<":J"<<f[key][i]<<endl;
}
//输出最大效益maxn
cout<<maxn<<endl;
return 0;
}
void search(int t){
//定义深搜函数
for(int i=1;i<=5;i++){
//共五种工作
if(!p[i]){
//当前工作没有被选中
f[tot][t]=i;//存储当前选择
p[i]=1;
if(t==5){
//到达搜索终点
solve();//设置解决函数
}else{
search(t+1);//没有到达终点需要继续搜索
}
p[i]=0;//回溯
}
}
}
void solve(){
//试着输出每一种方案
//出现0的情况,先去0;
int k=1;
while(!f[tot][k]){
f[tot][k]=f[tot-1][k];
k++;
}
//去0成功,方案已经实现
//计算总效益,与maxn比较
int sum=a[f[tot][1]]+b[f[tot][2]]+c[f[tot][3]]+d[f[tot][4]]+e[f[tot][5]];
if(maxn<sum){
maxn=sum;//记录最大效益
key=tot;//记录最大效益方案
}
tot++;
}