前面的文章 点击打开链接 介绍了动态规划中的 0-1背包问题,下面给出一个拔河比赛的实例,在拔河比赛这个问题的求解策略就是采用了 0-1背包的解决思路。
问题描述:n 个人参加拔河比赛,每个人有自己的重量,现在需要把他们分成两组进行比赛,每个人属于其中的一个组。为使比赛公平,求使得两组重量差最小的分配。
分析问题:明显的,我前面已经说明,是要采用0-1背包来求解。
问题中要求:最终的队员分配要使得两组队的重量差最小,那么如何才可以实现呢?我们可以这样考虑:
假设所有队员的总质量为sum,那么两队A,B的平均质量 average = sum/2.
那么假如队员分配之后,A队的总重量“接近” average,那么间接的,B队的总重量也会”接近“average。这里的“接近”指的是队中的总重量 大于 或者 小于(当然也有可能是相等)average某一个值,这个值相对来说是小的。那么这样分配的最终结果就会呈现出:两组队的重量差最小。
那么现在我们就可以采用 0-1背包来解决这个问题。
也就是说,这个背包的大小是 average,那么在可供选择的队员中选择,使到,选择的队员总质量不超过 <= average (也就是“接近”average),那么这样就可以使选择的队员总质量达到最接近average,那么间接的,剩下的所有队员都给另一个,其总质量就不小于 >= average。这样两队之间的质量差也就可以最小了。
下面给出实现的代码:
对于队员,我设置了一个结构体表示:
//定义一个拔河队员的结构体
typedef struct people
{
int number; //队员编号,从1开始
int weight; //队员重量
char team; //队员所在队:A队或者B队
} peoples;
注意:这里设置一个char team;的作用是这样的,我们假设所有的队员初始的时候都是B队的,那么在执行 0-1 背包的选择(A队选队员)过程中,如果符合要求的,就修改 team = 'A',那么就进行了标记。
下面贴出完整的代码: