我很难找到如何有效地解决这个问题。让我来描述一下:
“一位努力工作的妈妈为她的3个孩子Amelia,Jessica和Bruno购买了几种具有不同营养价值的水果。两个女孩都超重,他们非常恶毒,总是让可怜的布鲁诺一无所有,所以他们的母亲决定分享食物以下列方式:注意:原始问题的描述不同,但想法是一样的,我不希望我的同学在google寻求帮助时找到这篇文章。
我老师给出的一个测试用例如下:
The fruit list has the following values { 4, 2, 1, 8, 11, 5, 1}
Input:
7 -----> Number of Fruits
4 2 1 8 11 5 1 ----> Fruits Nutritional Values
Output:
1 11 ----> One fruit, their nutritional values sum for Amelia
5 ----> Position of the fruit in the list
3 11 ----> Three fruits, their nutritional values sum for Jessica
1 2 6 ----> Position of the fruits in the list
3 10 ----> Three fruits, their nutritional values sum for Bruno
3 4 7 ----> Position of the fruits in the list
注意:我知道有几种方法可以让孩子们熟悉水果,但只要遵循规则A> = J> = B就无所谓。
首先,我制作了一个生成所有子集的算法,每个子集都有它们的总和,以及正在使用的位置。该方法很快被丢弃,因为水果列表最多可以有50个水果,子集算法是O(2 ^ n)。我的内存耗尽了。
我的第二个想法是使用动态编程。在列标题中我将拥有Fruit's List的位置,在行标题中相同,用字母很难解释所以我将提前做一个表格用于上一个例子{4,2,1,8 ,11,5,1}。
00 01 02 03 04 05 06 07
00
01
02
03
04
05
06
07
每次我们前进到下面的行时,我们添加1,2,3,...,7
的位置 00 01 02 03 04 05 06 07
00 00 <---No positions in use
01 04 <---RowPosition 1 + Column Position(Column 0) (4+0)
02 06 <---RowPosition 1 + RowPosition 2 + Column Position (4+2+0)
03 07 <---RP(1) + RP(2) + RP(3) + CP(0) (4+2+1+0)
04 15 <--- (4+2+1+8+0)
05 26
06 31
07 32 <--- (4+2+1+8+11+5+1+0)
现在你知道它是怎么回事让我们添加第一行
00 01 02 03 04 05 06 07
00 00 04 02 01 08 11 05 01 <-- Sum of RP + CP
01 04 00 06 05 12 15 09 05 <-- Sum of RP(0..1) + CP
02 06
03 07
04 15
05 26
06 31
07 32
我把00放在第一位置已经投入使用了。完成的表格看起来像这样。
00 01 02 03 04 05 06 07
00 00 04 02 01 08 11 05 01
01 04 00 06 05 12 15 09 05
02 06 00 00 07 14 17 11 07
03 07 00 00 00 15 18 12 08
04 15 00 00 00 00 26 20 16
05 26 00 00 00 00 00 31 27
06 31 00 00 00 00 00 00 32
07 32 00 00 00 00 00 00 00
现在我们有了这张桌子。我将营养价值的总和除以孩子的数量,32/3 = 10.6667,上限为11.我试着检查11,如果它在表中,我选择它并标记行的位置和使用的表的列,然后我会尝试再次检查11,如果它在表中我选择它,否则看10或9等,直到我找到它。然后,我会标记所使用的各自位置,然后将未使用的位置相加以获得布鲁诺的果实。
我知道必须有更好的方法来做到这一点,因为我在我的方法中发现了一个缺陷,该表只有几个子集的总和。因此,在一些测试案例中,这可能会有害。也许是3D Memoization Cube?,我认为它会占用太多内存,而且我的限制也是256MB。
哇,我没有意识到我打了这么多x.X.我希望我不会得到很多东西;博士。任何帮助/指南将不胜感激:D编辑:我制作了生成表格的代码,以防有人想要试用。
static void TableGen(int[] Fruits)
{
int n = Fruits.Length + 1;
int[,] memo = new int[n, n];
for (int i = 1; i < n; i++)
{
memo[0, i] = Fruits[i - 1];
memo[i, 0] = memo[i - 1, 0] + Fruits[i - 1];
for (int j = i + 1; j < n; j++)
memo[i, j] = memo[i, 0] + Fruits[j - 1];
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
Console.Write("{0:00} ", memo[i, j]);
Console.WriteLine();
}
}
答案 0 :(得分:1)
for(i = 0; i < count; i++)
{
currentFruit=Fruits.Max();
if(Amelia.Sum() + currentFruit < Jessica.Sum() + currentFruit)
{
Amelia.Add(currentFruit);
Fruits.Remove(currentFruit);
continue;
}
if(Jessica.Sum() + currentFruit < Bruno.Sum() + currentFruit)
{
Jessica.Add(currentFruit);
Fruits.Remove(currentFruit);
continue;
}
Bruno.Add(currentFruit);
Fruits.Remove(currentFruit);
}
这适用于具有相对相似值的水果。如果你添加的水果的价值大于所有其他水果的总和(我偶然做过一次)它会分解一点。
答案 1 :(得分:1)
略微计算密集的方式是以循环方式分配水果,从amelia的最高营养价值开始。
从那里开始,逐渐从阿米莉亚所持有的最低营养价值中循环出水果,并尝试(a)将水果交给杰西卡,或(b)用杰西卡持有的水果交换水果,同时仍然满足规则。
然后将相同的方法应用于jessica和bruno。重复这两个循环,直到不再进行交换或给出
稍微棘手,但可能更快,将同时给/交换jess / bruno。对于A持有的每2件水果,您将有4种选择尝试,如果您同时尝试和平衡J&amp; B.
对于更快的算法,您可以尝试在数学堆栈交换站点询问,因为这是一个集理论问题。