工作分配——搜索与回溯

题目描述 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\n",64+i,gongzuo[i]);//第几个人做第几项工作
42     }
43     printf("total=%d\n",zhongjie);//输出最大效益
44     return 0;
45 }
时间: 2024-10-02 13:00:56

工作分配——搜索与回溯的相关文章

1990 工作分配

1990 工作分配 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 青铜 Bronze 题解 查看运行结果 题目描述 Description 新录A.B.C三个工人,每人分配一个工种,每个工种只需一人,经测试,三人做某种工作的效率如下表所示.如何分配三人的工作才能使他们工作效益最大? 输入描述 Input Description 为1个3×3的矩阵,矩阵的第一行为A做三种工作的效益,第二行为B做三种工作的效益,第三行为C做三种工作的效益.输入保证各效益的范围满足1≤N≤2147

在物理表中分配搜索帮助

在物理表中分配搜索帮助有两种办法: 1.就是刚才我们分配搜索帮助在一个数据元素中,定义表的时候再把该字段分配给这张表,这样这张表中的这个字段就具有此搜索帮助的功能. 2.在表中指定字段分配搜索帮助,具体如下: 2. 3. 4. 效果如下,查询表的时候: 在abap中可以直接参考该表字段建立就无需指定搜索帮助了. PARAMETERS:p_vbeln TYPE ZSPFLI-VBELN.

一本通搜索与回溯例题5.2

[题目描述] 排列与组合是常用的数学方法,其中组合就是从n个元素中抽出r个元素(不分顺序且r≤n),我们可以简单地将n个元素理解为自然数1,2,…,n,从中任取r个数. 现要求你用递归的方法输出所有组合. 例如n=5,r=3,所有组合为: 1 2 3   1 2 4   1 2 5   1 3 4   1 3 5   1 4 5   2 3 4   2 3 5   2 4 5   3 4 5 [输入] 一行两个自然数n.r(1<n<21,1≤r≤n). [输出] 所有的组合,每一个组合占一行且

递归,搜索,回溯,最优路径(线段)

基本信息 内存:520kB 时间:0ms 语言:G++ 题目链接http://bailian.openjudge.cn/practice/solution/4779752/ 解题报告: 1.输入表格时,由于这里有空格,不能用scanf函数. 2.gets(board[i]+1) 不要把第一列刷去. 3.回溯mark[y][x]=false;这里在Search玩后,一定要将mark[y][x]改为false.否则下一次的搜索将不会访问到这个点. 4.方向最好用数组形式表示. 5.最重要的一点是:这

为数据元素DATA Element分配搜索帮助

搜索帮助可以分配给数据元素,程序中可以直接参照该数据元素具体如下: 1. 2. 程序中使用. PARAMETERS:p_vbeln TYPE ZVBELN_01. 3. 效果:

马的遍历——搜索与回溯

题目描述 Description 中国象棋半张棋盘如图所示.马自左下角往右上角跳.今规定只许往右跳,不许往左跳.比如图4(a)中所示为一种跳行路线,并将所经路线打印出来. 输入输出格式 Input/output 输入格式:无输出格式: 第一行:一个整数total表示第几种跳法 第二行:0,0-->2,1-->3,3-->1,4-->3,5-->2,7-->4,8 输入输出样例 Sample input/output 样例测试点#1 输入样例: 无 输出样例: 1 0,0

搜索与回溯算法

[例]任何一个大于1的自然数n,总可以拆分成若干个小于n的自然数之和. 当n=7共14种拆分方法: 7=1+1+1+1+1+1+1 7=1+1+1+1+1+2 7=1+1+1+1+3 7=1+1+1+2+2 7=1+1+1+4 7=1+1+2+3 7=1+1+5 7=1+2+2+2 7=1+2+4 7=1+3+3 7=1+6 7=2+2+3 7=2+5 7=3+4 total=14 1 [参考程序] 2 program ex5_3; 3 var a:array[0..100]of integer

工作中搜索页面搜索记录功能的封装(存储到本地)

//!*封装添加搜索记录功能 (newRecord:str,当参数为空时为获取历史记录; num:记录数,默认为12条;) function addHisRecord(newRecord, num){ num = num || 12; //获取本地存储的记录 var hisRecord_str = window.localStorage.getItem('hisRecord_str'); //当获取到的值为null时,创建一个空数组存储进去 if(typeof hisRecord_str ==

拆数——搜索与回溯

题目描述 Description 求任何一个大于0的自然数n,总可以拆分成若干个小于n的自然数之和 输入输出格式 Input/output 输入格式:一个正整数n输出格式:n=XXX+XXX+XXX+XXX… total(总方案数)=XXX 输入输出样例 Sample input/output 样例测试点#1 输入样例: 7 输出样例:7=1+1+1+1+1+1+17=1+1+1+1+1+27=1+1+1+1+37=1+1+1+2+27=1+1+1+47=1+1+2+37=1+1+57=1+2+