我遇到了一个问题,我需要一些来自SO的聪明人的帮助。我想把n个球员分成m队。每个玩家都有不同的游戏能力。能力由正整数或负整数表示。团队的总能力只是分配给该团队的人员的能力分数的总和。
我的目标是找到具有最大总能力的团队与具有最低总能力的团队之间的最小可能差异。每个参与者都必须将约束放在一个团队中,每个团队必须至少有一个成员。
例如,如果我有以下具有异能的球员:[1,2,3,4,5,6,7],并希望组建三支球队。因此,具有最大总能力的团队与具有最小总能力的团队之间的最小可能差异是1.一种可能的解决方案是:
第1队:1 + 3 + 6 = 10
第2队:2 + 7 = 9
第3队:4 + 5 = 9
我试图通过以下策略来划分玩家:
1.分享能力
2.每次将剩余最高能力的球员分配给能力最低的组,直到没有球员为止
此策略适用于某些问题。这是我到目前为止的代码:
public int minDifference(int numTeams, int[] abilities) {
ArrayList<ArrayList<Integer>> teams = new ArrayList<ArrayList<Integer>>();
int[] teamSum = new int[numTeams];
for(int i = 0; i < numTeams; i++){
teams.add(new ArrayList<Integer>());
teamSum[i] = 0;
}
Arrays.sort(abilities);
for(int i = abilities.length - 1; i >= 0; i--){
int minSum = teamSum[0];
int minNum = 0;
for(int j = 1; j < numTeams; j++){
if(teamSum[j] < minSum){
minSum = teamSum[j];
minNum = j;
}
}
teams.get(minNum).add(abilities[i]);
teamSum[minNum] += abilities[i];
}
Arrays.sort(teamSum);
System.out.println(teamSum[numTeams - 1] - teamSum[0]);
return teamSum[numTeams - 1] - teamSum[0];
}
现在我被卡住了。我的想法是比较两个团队。说A和B.玩家Tom来自A和Jerry来自B.如果A - B = 10,Tom - Jerry = 3;然后交换汤姆和杰瑞。所以A - B = 4 现在。并继续这样做。但似乎有太多的比较(因为你还需要计算两队球员之间的差异),我不知道何时停止(意味着我怎么知道它是最小的)。
答案 0 :(得分:0)
我很确定这是一个NP问题,因为决定我们是否可以将球员分成两支没有差别的球队是属于NPC的subset-sum problem。这个问题的任何多项式时间解决方案都不正确(或者你可以说NP = P),所以不要浪费时间思考多项式解决方案,只是尝试完全搜索(我的意思是所有m ^ n可能的解决方案..),如果你认为它太慢了,你可以尝试启发式搜索。
答案 1 :(得分:-1)