我有一个名单。
我想将此列表分区为指定大小的组。所有组应该等于或小于指定的大小,组中的组大小尽可能相等,并且尽可能接近指定的大小。
什么算法(如果可能,请使用Java-esque伪代码!)确定最合适的组大小?
例如:
列表包含13个名称 - 最大团队规模3。 输出(组大小):3,3,3,2,2
列表包含13个名称 - 最大团队规模4。 输出:4,3,3,3
列表包含31个名称 - 最大团队规模5。 输出:5,5,5,4,4,4,4
列表包含31个名称 - 最大团队规模6。 输出:6,5,5,5,5,5
列表包含31个名称 - 最大团队规模10。 输出:8,8,8,7
答案 0 :(得分:4)
这很简单。您计算N div M
的结果并添加1以获得正确的数组数(N是列表长度,M是最大团队大小),然后迭代所有数组以添加项目,直到用完项目为止
示例:43个名称,最大团队编号4 => 43 mod 4 + 1 = 11,保持为3.所以11个阵列(10个有4个,1个有3个)
答案 1 :(得分:2)
我不会为此编写代码,但是
这显然只适用于接近锻炼的输入;如果最大团队规模与列表规模相比较大,则会失败。
答案 2 :(得分:2)
如果列表中的项目数为N
且子列表中的最大项目数为K
,则问题的解决方案来自求解Linear Diophantine Equation
K*x + (K-1)*y = N
有其他约束
x > 0
y >= 0
其中x
是确切大小K
的子列表数量,y
是长度为K-1
的子列表数量。
编辑:由于等式的系数总是相互偏离,因此解决方案非常简单:
int m = (N+K-1)/K;
int x = N - (K-1)*m; // Number of "full" lists
int y = K*M - N; // Number of off-by-one lists
示例1:
N = 31, K = 5
m = (31+5-1)/5 = 7
x = 31 - (5-1)*7 = 3 // 3 lists of 5 items
y = 5*7 - 31 = 4 // 4 lists of 4 items
示例2:
N = 32, K = 4
m = (32+4-1)/4 = 8
x = 32 - (4-1)*8 = 8 // 8 lists of 4 items
y = 4*8 - 32 = 0 // no lists of 3 items
查找一个在网上求解线性丢番图方程的算法 - 如果你理解Euclidean algorithm那就不那么复杂了。没有约束的方程的解的数量是无限的,但是一旦你添加约束,你应该得到一个解决方案。
答案 3 :(得分:0)
public class Q {
public static void q(int size, int maxTeamSize) {
int numOfTeams = size / maxTeamSize;
int mod = size % maxTeamSize;
numOfTeams += (mod > 0) ? 1 : 0;
System.out.print("\n(" + size + ":" + maxTeamSize + ")");
for (int i = 0; i < numOfTeams; i++) {
System.out.print(" " + (size / numOfTeams + ((i < mod) ? 1 : 0)));
}
}
public static void main(String[] args) {
q(13, 3);
q(12, 4);
q(31, 5);
q(31, 6);
}
}