在Java中寻找最大组合总和

5
假设你有一组数字如下所示:
[A,B,C]

[6, 4.5, 6]
[7, 6, 5]
[9, 4.5, 6]

每个类别(A、B或C)中只能使用一个数字来找到最大的总和。在这种情况下,A=9,B=6和C=6将产生最大的总和21。最大的总和不能是22(9+7+6),因为9和7都属于A类别。

在Java中如何实现?

我遇到了麻烦,因为选择每个类别中的最大值并不能保证获得最大的总和。有些类别可能会被迫选择较小的值,从而降低总和。请记住,每个类别的AND集合中只能选择一个数字。


2
似乎是要找到每列中最大的数字并将它们相加...那你尝试过什么了吗? - dacwe
2
具体问题是什么?您需要使用Java编写代码,使用循环比较数字并添加结果。 - Peter Lawrey
1
我在寻找最大值时遇到了麻烦,因为在每个类别中选择最大值并不能保证获得最大的总和。有些类别可能会被迫选择较小的值,从而降低总和。请记住,每个类别中只能选择一个数字的AND。 - user1584575
3
如果你实际花时间阅读这个问题,那么这是一个非常合理的问题。我不确定为什么有些人要对这个用户挑剔。 - dfb
1
如果你仍然遇到麻烦,我建议你重新发布。如果你能够包含一个(Java)的尝试,哪怕它是错误的,你会得到更好的回复,因为SO经常收到很多“帮我做这个”的请求。如果你还没有尝试过,请从这里开始:https://en.wikipedia.org/wiki/Depth_first_search,并随着问题的出现提问。@BrianJ的答案虽然不正确,但是引用了八皇后问题,应该是类似的实现。 - dfb
显示剩余5条评论
3个回答

1

这有点像八皇后问题,你需要在棋盘上放置8个皇后,而不让它们互相攻击。(如果你不懂国际象棋,不要担心这个比喻)。

假设你的示例数组:

[6, 4.5, 6]
[7,   6, 5]
[9, 4.5, 6] 

找到整个数组中最大的值(在这种情况下是9),并阻止其所在的行和列。

你的新数组看起来像这样(x代表不再有效的选择)。

[x, 4.5, 6]
[x,   6, 5]
[x,   x, x]

重复这个过程,直到你从每一列和每一行中选择一个值为止。

现在,作为一个警告,对于当前最大值有多个位置(例如在示例的第二步中,有两个6),会导致一些更多的条件。我会留下一些乐趣给你,但如果需要的话,我很乐意提供更多帮助。

警告

尼尔C.在评论中指出,此答案无效。 具体反例:

[10, 9, 1]
[ 9, 1, 1]
[ 1, 1, 1]

我目前手头上还没有解决方案,但我想留下这个答案以便在找到正确的解决方案时提供帮助。


2
这个算法不总是有效:考虑数组{{10,9,1},{9,1,1},{1,1,1}},该算法给出的结果为10+1+1=12,但实际上结果应该是9+9+1=19 - Niall C.
@Niall C. 我明白你的观点。我需要再考虑一下。感谢你提供的反例。 - Brian J

0

一种简单的暴力搜索方法是生成长度为N的所有排列,其中N是类别的数量。然后,对于每个排列,计算所有i的Matrix[i][Permutation[i]]之和,并取最大值。


-2
这是关于我如何做的一些想法。
假设您将数据存储在一个整数的二维数组中。
int [] [] data = new int [rows] [columns]

所以在这种情况下,列是 A、B、C 等。
在搜索最大值时,您需要像这样进行迭代: data[i][fix] 这样列是固定的,而行在循环中更改。
例如,如果您想获取 A 的最大值,并且使用我建议的 2D 数组,则:
int [] [] data = new int [3][3];

那么你需要从data [0] [0]data [1] [0]data [2] [0]这个集合中获取A的最大值。

编辑:

这里有一个可能的解决方案供您参考。

//here is our data array.
int [][] data = new int[3][];

//fill up with som random data
data[0] = new int[]{10,20,4,5,56,87,9};
data[1] = new int[]{1,65,0,10,3};
data[2] = new int[]{34,5,6,67,3,54};

//get the biggest arrays length
int maxArrayLength = 0;
for(int i=1; i<data.length; i++)
{
    if(data[i].length > data[maxArrayLength].length)
        maxArrayLength = i;
}
maxArrayLength = data[maxArrayLength].length;

//collect the max in each category
int [] categoryMax = new int[maxArrayLength];

//loop through the categories
for(int i=0; i<maxArrayLength; i++)
{
    //in each iteration we get a winner
    int categoryWinner = 0;

    // now loop through the values of the current category
    for(int j=0; j<data.length; j++)
    {
        int [] actualArray = data[j];
        int [] winnerArray = data[categoryWinner];

        //check if we are in the bounds, if so, then perform a simple maxsearch
        if(i<actualArray.length)
            if(actualArray[i] > winnerArray[i])
            categoryWinner = j;
    }

    //set the current element of the winners array.
    categoryMax [i] = data[categoryWinner][i];
}

int sum = 0;

// we are ready, print it out!
for(int i=0; i<categoryMax.length; i++)
{
    System.out.println((i+1) + ". groups winner: " + categoryMax[i]);
    sum+=categoryMax[i];
}
System.out.println(sum);

1
实际上,这不是我的作业。我只是在尝试找出如何找到最大值。只需浏览并找到每组中的最大值就很容易了。然而,假设一个类别在后面的集合中有更大的值,我无法想出如何返回并重新进行计算。此外,如果我将一个类别更改为最大值,它并不能保证我会得到最大的总和。另一个类别可能被迫降低价值。 - user1584575
哦,那么您可以通过数组的.length属性始终检查是否缺少值。 - Balázs Édes
我不明白。数组.length 怎么帮助我找到最大值? - user1584575
它只在循环中帮助你意识到是否超出了数组的边界。所以你在实现maxsearch时遇到问题了吗? - Balázs Édes
这实际上根本没有解决原始问题。 - dfb
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接