Матч
305, Нечестный
дележ (UnfairDivision)
Дивизион 1, Уровень 2; Дивизион 2, Уровень 1
Альберт и его две сестры Бетти и
Карина делят имущество. Стоимости вещей, доставшихся в наследство, выписаны на
куске бумаги и задаются массивом assets. Альберт берет ножницы и
разрезает бумагу между некоторыми двумя числами. Потом Бетти таким же образом
разрезает один из кусков. Далее Карина выбирает кусок с максимальной суммой. Из
оставшихся двух кусков выбор делает Бетти. Последний кусок достается Альберту.
Каждый из участников при выборе
старается получить максимальную сумму наследства. Сестры обижены на брата, и в
своих выборах будут наказывать его, если только при этом не пострадает их
прибыль. Например, если у одной из сестер есть два разные варианта получить одну
и туже сумму имущества, то она выберет тот из вариантов, при котором ее сестра
получит больше.
Найти максимальную сумму, которую
может обеспечить Альберт своим первым разрезом.
Класс: UnfairDivision
Метод: int
albertsShare(vector<int> assets)
Ограничения:
assets содержит
от 3 до 50 элементов, 1 £ assets[i] £ 1000.
Вход. Массив assets, содержащий стоимости элементов
имущества.
Выход. Максимальная сумма, которую может обеспечить себе Альберт
своим выбором.
Пример входа
assets |
{50, 90, 10, 100} |
{1, 1, 1, 1, 1, 1, 1, 1,
1} |
{1, 2, 3, 4, 5, 6, 7, 8,
9} |
{5, 5, 5} |
Пример выхода
50
2
10
5
РЕШЕНИЕ
перебор
Рассматриваем
все возможные варианты разреза куска бумаги Альбертом. Пусть он делает разрез
после числа a.
Далее перебираем все
возможные разрезы Бетти. Пусть она делает разрез после числа b (b
¹ a). Ищем суммы чисел, записанных на трех кусках бумаги, сортируем их по
возрастанию в массиве s. Карина
получает максимальную сумму наследства, равную s[2]. Бетти берет кусок с суммой s[1], Альберту достается s[0]. Для заданного a, перебирая все возможные значения b, находим наилучший выбор Бетти.
При этом если текущий выбор Бетти s[1] равен ее
наилучшему bestBetty, то выбираем тот, при котором
Альберту достанется меньше. Среди всех разрезов Альберта выбираем тот, при
котором он получит большую часть наследства.
ПРОГРАММА
#include <cstdio>
#include <vector>
#include <numeric>
#include <algorithm>
using namespace std;
class UnfairDivision
{
public:
int albertsShare(vector<int>
assets)
{
int albert = 0, bestAlbert = 0,
bestBetty, a, b;
for(a = 1; a < assets.size(); a++)
{
bestBetty = 0;
for(b = 1; b < assets.size(); b++)
{
if (a == b) continue;
int s[] =
{accumulate(assets.begin(),assets.begin()+min(a,b),0),
accumulate(assets.begin() +
min(a,b),
assets.begin() + max(a,b),0),
accumulate(assets.begin() +
max(a,b),assets.end(),0)};
sort(s,s + 3);
if ((s[1] > bestBetty) || (s[1] ==
bestBetty && s[0] < albert))
{
bestBetty = s[1];
albert = s[0];
}
}
if (albert > bestAlbert) bestAlbert =
albert;
}
return bestAlbert;
}
};