题目是这样的:
有4个工人,要分别指派他们完成4项工作,每人做各项工作的时间如下表:
A B C D
甲 15 18 21 24
乙 19 23 22 18
丙 26 17 16 19
丁 19 21 23 17
问指派哪人去做什么工作?
问消耗时间最小是多少?
传统的DP运筹问题,用 0—1规划 找好转移方程就行了。
#include <iostream>
#include <algorithm>
#include <math.h>
#define maxn 0x3f3f3f3f
using namespace std;
/*........int p[4]={1,2,4,8}............................
..........配合int way[6][16] 的状态转移.................
......................................................*/
int p[4]={1,2,4,8};
/*........int rec[6][16]................................
..........用于找出每个 way[a][state] 状态下的最小工时...
......................................................*/
int rec[6][16];
/*........int way[6][16]................................
..........记录转移状态的数组,用于递归输出方案..........
..........用 0-1规划 构造 way[6][16]数组记录工人工作....
......................................................*/
int way[6][16];
/*........int map[4][4].................................
..........输入数据 .....................................
..........用于存储每个工人的每项工作耗时................
......................................................*/
int map[4][4]={{15,18,21,24},{19,23,22,18},{26,17,16,19},{19,21,23,17}};
/*........int f(int a,int state)........................
..........前a个人,当前状态为state的时候的最小耗费时间..
..........state是一个2进制的数,大小是从0000-1111.......
..........当state从低到高,第i位的数为0,就表示之前第i项工作没有安排人做,为1表示做了
......................................................*/
int f(int a,int state)
{
if (a==5 && state==15) return 0;
if (rec[a][state]!=maxn) return rec[a][state];
for (int i=0;i<4;i++)
if ( ((p[i]&state)!=p[i]) && (f(a+1,state|p[i])+map[a-1][i])<rec[a][state] )
{
rec[a][state]=f(a+1,state|p[i])+map[a-1][i];
way[a][state]=state|p[i];
}
return rec[a][state];
}
/*........void out(int a,int state).....................
..........前a个人,当前状态为state的时候的最小耗费时间..
..........int func(int a)...............................
..........通过第a个人的 way[a][state]状态数组^state 找出第a个人的工作
......................................................*/
int func(int a)
{
for (int i=0;i<4;i++)
if (a==p[i]) return i+1;
}
void out(int a,int state)
{
if (a==5) return;
printf("第%d个人做第%d项工作\n",a,func(way[a][state]^state));
out(a+1,way[a][state]);
}
int main(void)
{
int i,j;
for (i=0;i<6;i++)
for (j=0;j<16;j++)
rec[i][j]=maxn;
printf("最小消耗时间:%d\n",f(1,0));
printf("方案如下:\n");
out(1,0);
return 0;
}
/*最小消耗时间:70......................................
方案如下:..............................................
第1个人做第1项工作......................................
第2个人做第4项工作......................................
第3个人做第3项工作......................................
第4个人做第2项工作....................................*/
Copy的@ jacksonislwj 的代码