0

我遇到了一个问题,我需要一些聪明人的帮助。我想将 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。A 的玩家 Tom 和 B 的玩家 Jerry。如果 A - B = 10,并且 Tom - Jerry = 3;然后交换汤姆和杰瑞。所以现在 A - B = 4。并继续这样做。但是好像比较太多了(因为你还需要计算两队球员之间的差异),我不知道什么时候停止(意味着我怎么知道它是最小的)。

4

2 回答 2

0

我很确定这是一个 NP 问题,因为我们是否可以将玩家分成 2 个没有差异的团队的决定是属于 NPC的子集和问题。这个问题的任何多项式时间解决方案都是不正确的(或者你可以说 NP=P),所以不要浪费时间思考多项式解决方案,只需尝试完整搜索(我的意思是所有 m^n 可能的解决方案..),如果你觉得太慢了,可以试试启发式搜索。

于 2013-07-12T09:53:30.413 回答
-1

我是这样想的。您可以添加所有能力并将其除以团队数量,而不是尝试提出总能力尽可能接近该数字的团队

于 2013-07-12T08:29:01.977 回答