ACM中的工作分配问题是一个典型的回溯问题,利用回溯思想能很准确地得到问题的解。下面就这个问题好好分析下。

问题描述:
    设有n件工作分配给n个人。为第i个人分配工作j所需的费用为c[i][j] 。试设计一个算法,计算最佳工作分配方案,为每一个人都分配1 件不同的工作,并使总费用达到最小。

解题思路:
    由于每个人都必须分配到工作,在这里可以建一个二维数组c[i][j],用以表示i号工人完成j号工作所需的费用。给定一个循环,从第1个工人开始循环分配工作,直到所有工人都分配到。为第i个工人分配工作时,再循环检查每个工作是否已被分配,没有则分配给i号工人,否则检查下一个工作。可以用一个一维数组x[j]来表示第j号工作是否被分配,未分配则x[j]=0,否则x[j]=1。利用回溯思想,在工人循环结束后回到上一工人,取消此次分配的工作,而去分配下一工作直到可以分配为止。这样,一直回溯到第1个工人后,就能得到所有的可行解。在检查工作分配时,其实就是判断取得可行解时的二维数组的一下标都不相同,二下标同样不相同。

样例分析:
    给定3件工作,i号工人完成j号工作的费用如下:
10 2 3
2 3 4
3 4 5

假定一个变量count表示工作费用总和,初始为0,变量i表示第i号工人,初始为1。n表示总的工作量,这里是取3。c[i][j]表示i号工人完成j号工作的费用,x[j]表示j号工作是否被分配。算法如下:

void work(int i,int count){
if(i>n)
return ;
for(int j=1;j<=n;j++)
if(x[j] == 0){
x[j] = 1;
work(i+1,count+c[i][j]);
x[j] = 0;
}
}

那么在这里,用回溯法的思想就是,首先分配的工作是:
10:c[1][1]  3:c[2][2]  5:c[3][3]  count=18;
   
    此时,所有工人分配结束,然后回溯到第2个工人重新分配:
10:c[1][1]  4:c[2][3]  4:c[3][2]  count=18;

第2个工人已经回溯到n,再回溯到第1个工人重新分配:
2:c[1][2]  2:c[2][1]  5:c[3][3]  count=9;

回溯到第2个工人,重新分配:
2:c[1][2]  4:c[2][3]  3:c[3][1]  count=9;

再次回溯到第1个工人,重新分配:
3:c[1][3]  2:c[2][1]  4:c[3][2]  count=9;

回溯到第2个工人,重新分配:
3:c[1][3]  3:c[2][2]  3:c[3][1]  count=9;

这样,就得到了所有的可行解。而我们是要得到最少的费用,即可行解中和最小的一个,故需要再定义一个全局变量cost表示最终的总费用,初始cost为c[i][i]之和,即对角线费用相加。在所有工人分配完工作时,比较count与cost的大小,如果count小于cost,证明在回溯时找到了一个最优解,此时就把count赋给cost。
    到这里,整个算法差不多也快结束了,已经能得到最终结果了。但考虑到算法的复杂度,这里还有一个剪枝优化的工作可以做。就是在每次计算局部费用变量count的值时,如果判断count已经大于cost,就没必要再往下分配了,因为这时得到的解必然不是最优解。

#include<iostream>
using namespace std;
int n,cost=0;
int x[100],c[100][100];
void work(int i,int count){
if(i>n && count<cost){
cost = count;
return ;
}
if(count<cost)
for(int j=1;j<=n;j++)
if(x[j] == 0){
x[j] = 1;
work(i+1,count+c[i][j]);
x[j] = 0;
}
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>c[i][j];
x[j] = 0;
}
cost+=c[i][i];
}
work(1,0);
cout<<cost<<endl;
system("pause");
return 0;
}

算法分析之工作分配问题相关推荐

  1. 回溯法解决工作分配问题及分析

    1.实践题目 工作分配问题 2.问题描述 设有n件工作分配给n个人.将工作i分配给第j个人所需的费用为cij . 设计一个算法,对于给定的工作费用,为每一个人都分配1 件不同的工作,并使总费用达到最小 ...

  2. 工作分配问题 NOJ 1288 裸KM算法

    工作分配问题 时间限制(普通/Java) : 20000 MS/ 30000 MS          运行内存限制 : 65536 KByte 总提交 : 55            测试通过 : 3 ...

  3. 回溯法解决工作分配问题

    回溯法解决工作分配问题 问题描述: 设有n件工作分配给n个人.为第i个人分配工作j所需的费用为c[i][j] .试设计一个算法,计算最佳工作分配方案,为每一个人都分配1 件不同的工作,并使总费用达到最 ...

  4. 工作分配问题【回溯算法】

    Problem Description 设有n件工作分配给n个人.将工作i分配给第j个人所需的费用为 c i j c_{ij} cij​.试设计一个算法,为每一个人都分配1件不同的工作,并使总费用达到 ...

  5. 3. 工作分配问题(回溯法)设有n件工作分配给n个人。。。

    问题描述: 设有n件工作分配给n个人.将工作i分配给第j个人的费用为cij,请设计算法,为每个人都分配1件不同的工作,并使得总费用达到最小. 实现提示:该问题的解空间是一棵排列树,可用搜索排列树的回溯 ...

  6. 回溯法求解:工作分配问题

    一.问题描述: 设有 n 件工作分配给 n 个人.将工作 i 分配给 j 个人所需的费用为  .试设计一个算法,为每个人都分配 1 件不同的工作,并使得总费用最小. 输入格式:第一行有 1 个正整数 ...

  7. 实现分派问题的回溯算法java_工作分配问题 Java 回溯 | 学步园

    问题描述: 设有n件工作分配给n个人.为第i个人分配工作j所需的费用为c[i][j] .试设计一个 310 2 32 3 43 4 5 import java.util.Scanner; public ...

  8. 工作分配问题pascal程序

    这题我是用搜索的方法来做的 搜的时候,如果当前的费用大于tj,那么就不用再搜了,小于tj就把当前的费用放进tj里,最后输出tj var n,i,j,tj:longint; a:array[0..100 ...

  9. sdut算法分析oj题目整合

    A-众数问题(分治算法A-D) Description: 给定含有n个元素的多重集合S,每个元素在S中出现的次数称为该元素的重数.多重集S中重数最大的元素称为众数.例如,S={1,2,2,2,3,5} ...

最新文章

  1. SAP直接踢人下线 SM04
  2. python从random生成列表_Python 学习DAY 17 列表生成式,生成器,迭代器,time模块,random模块...
  3. 数据结构与算法 | 顺序表
  4. kubernetes1.8.4 安装指南 (基于静态Pod方式安装)
  5. 获取GridView中RowCommand的当前选中行的索引或主键Id
  6. html5页面转场,基于HTML5 SVG的页面过渡切换效果
  7. 阿里可观测性数据引擎的技术实践
  8. 无代码调整聚类热图分支顺序
  9. Blog主场转至51CTO.com
  10. 链表的基本操作Basic Operation of LinkList
  11. MySql 语法(完整版)
  12. CS188-Project4
  13. 百度小米滴滴躬身入局,新能源造车如此多娇,引无数大厂竟折腰?
  14. SOLIDWORKS motion如何进行运动仿真
  15. 作为喜爱3D游戏动漫建模的你,如果还不知道次世代游戏贴图的这些技巧,真是太可惜了
  16. 日志自动分析和解析开源工具
  17. tp-link 怎么打开ssh服务_如何用Xshell远程连接VPS服务器
  18. 细思极恐-你真的会写java吗?
  19. layui 前端计算
  20. 收藏了,挺有意思的生成太极图

热门文章

  1. ModuleNotFoundError: No module named
  2. Grafana 介绍和使用
  3. 电脑默认按住了ctrl键的解决办法
  4. 【C#学习笔记】TextBox使用
  5. Python编写带音效游戏——击球打玻璃块
  6. 马士兵Python基础版2020教程P1-P57 PPT笔记+课堂代码
  7. 自媒体运营之:微博认证怎么弄黄v?(个人橙v认证)
  8. 深入理解epoll模型
  9. 高压功率放大器ATA-4052在径向驻波型超声波电机研究中的应用
  10. 直接计算法弱磁控制策略 额定转速以下采用最大转矩电流比控制