如果我有两个号码,即N
和M
,我必须找出如何在N
个小组中划分M
人,以便最少对在每个团队中形成,然后我该怎么办呢? (此外,每个团队应至少有一名成员)
例如,如果我有N = 6
和M = 3
,
那么,每个团队应该有2个人。因此,共有3支队伍,意味着3对队伍。
我知道我必须分发,以便分发应尽可能均匀。但是我无法为它提出合适的算法。谢谢!
答案 0 :(得分:1)
这很简单。首先,在每个团队中加入n/m
人。
你剩下n%m
(n modolus m)的玩家,将他们随机分成小组,但是每个小组都可以获得其中一个"额外的"播放器。
直觉为什么这是真的很简单,在m = 2的情况下:
您需要将n个玩家分成x
和n-x
,并且您希望最小化对数:
x(x-1)/2 + (n-x)(n-x-1)/2 =
= (x^2-x + n^2 -2nx + x^2 -n +x)/2
使用衍生物查找最小值:
d(x^2-x + n^2 -2nx + x^2 -n -x)/2/dx = 2x -1 -2n +2x +1 = 4x-2n
看看上面的等于0:
4x-2n = 0 -> x=n/2
对于任何n/m
,结果都会相似(尽可能接近m>0
),更难以证明。
答案 1 :(得分:0)
与另一个答案类似,但有一个更直接的证据的大纲。假设你有两个队员,他们的队员数量差异超过1,即一队有k队员,一队有k + j队员,其中k> = 1且j> = 2。表明如果你将一个玩家从拥有k + j玩家的团队移动到拥有k个玩家的团队,那么你将使用二项式系数得到一个严格较小数量的对。
答案 2 :(得分:0)
n / m
。n % m
。现在您有两个选择:
我知道你选择了选项2.
我将向您展示Java中可能对您有帮助的代码。
(我知道你的问题没有java标签,但是很容易理解的高编程语言)
int people = n;
int numberOfTeams = m;
int peopleAlone = n;
int initialPeopleForTeam = n/m;
//This is an array of teams where each element of array is a team,
// and his value the number of people that have the team.
int teams[] = new int [numberOfTeams];
//each team starts with n/m players.
for (int i = 0; i < m; i++){
teams[i] = initialPeopleForTeam;
peopleAlone = peopleAlone - initialPeopleForTeam;
}
//While the number of people alone is not 0, I'll give one more person to each team.
int index = 0;
while (peopleAlone > 0){
teams[index] = teams[index] + 1;
index++;
peopleAlone--;
}