Не могу понять алгоритм решения

В общем, пытаюсь решить одну задачу и не могу найти алгоритм её решения. Вот условие и пример вывода с пояснением: введите сюда описание изображения

Я пробую определить формулу для вычисления, но ничего не получается. Сначала исходил из того, что согласно условия задачи стоимость доставки не зависит от количества доставляемого товара. Тогда наиболее выгодный товар с наименьшей стоимостью delivery, но другие параметры тоже влияют на выбор наиболее выгодного товара. Пробовал вычислить стоимость доставки одной единицы товара delivery : amount*count, но ничего это не дало. Может надо найти коэффициент какой-то. Вот какой - не могу понять. Натолкните на решение этой задачи.

Условие задачи текстом:

Компания решила оптимизировать поставки продукции. У каждого из отделов по производству в наличии есть ограниченное количество партий готовой продукции, количество партий count: в партии или 50 штук, или 100, или 500, или 1000 штук - хранится в amount, цены указаны в price. Продукция у всех отделов одинаковая. Сумма доставки в центральный магазин у каждого из отделов разная, но у всех она не зависит от количества доставляемого товара - хранится в delivery. Необходимо рассчитать оптимальную поставку n штук продукции.

Примечание:

стоимость продукции и доставки не может совпадать у разных отделов мы не можем купить дробное число партий, то есть у последнего поставщика покупаем всю партию, несмотря на то, что нам нужна часть На входе:

n - необходимое количество продукции

price - массив цен за одну партию продукции

amount- массив с количеством продукции в одной партии продукции

count - массив с количеством партий продукции в наличии

delivery - массив стоимости доставки для всех поставщиков, независимо от количества купленных партий продукции

На выходе: строка - номера поставщиков через запятую (поставщики нумеруются с 0), у которых мы будем заказывать продукцию, в порядке приоритета. То есть у одного (наиболее выгодного) купили всё, переходим к другому и так до конца, пока не купим достаточное количество n

Пример:

n=1000

price=[100, 200, 300, 400]

amount=[50, 100, 500, 100]

count=[4, 5, 7, 3]

delivery=[0, 100, 5000, 1000]

getResult(n, price, amount, count, delivery) → 0,1,3 // сначала покупаем у 0-го поставщика 4 * 50 продукции, затем у 1-го 5 * 100, остальное покупаем у 3-го


Ответы (1 шт):

Автор решения: Sergey Izotov

Моё решение ниже. Не проходит 4-ый тест, мне кажется там тест неверный, вручную даже считал. Алгоритм состоит в том, чтобы вычислить цену товара за единицу с учетом доставки. Формула такая S=(p*tA+d)/tA, где p-price, tA - total amount (=amount но не более n) максимальное нужное число товара, tC - total count (=n/amount с округлением вверх) максимально нужное число партий. К тому же нужно учитывать, что при покупке последней партии весь товар не нужен, поэтому нужно пересчитать единицу стоимости товара, для этого цикл while и строка: n -= amount.get(provider) * count.get(provider);

   public static String getResult(int n, List<Integer> price, List<Integer> amount, List<Integer> count, List<Integer> delivery) {
        int products = n;
        int maxAmount = 0;
        int provider;
        List<Integer> result = new ArrayList<>();
        List<Integer> providers = new ArrayList<>();
        Map<Integer, Double> costPerUnit = new HashMap<>();
        StringBuilder sb = new StringBuilder();
        while (true) {
            for (int i = 0; i < price.size(); i++) {
                if (result.contains(i)) {
                    costPerUnit.put(i, Double.MAX_VALUE);
                    continue;
                }
                int totalCount;
                double needCount = (double) n / (double) amount.get(i);
                if (needCount > count.get(i)) {
                    totalCount = count.get(i);
                } else {
                    totalCount = (int) Math.ceil(needCount);
                }
                int totalAmount = amount.get(i) * count.get(i);
                if (totalAmount > n) {
                    totalAmount = n;
                }
                double cost = ((double) price.get(i) * totalCount + (double) delivery.get(i)) / (double) totalAmount;
                costPerUnit.put(i, cost);
            }
            costPerUnit.entrySet().stream().sorted(Map.Entry.comparingByValue()).forEach(e -> providers.add(e.getKey()));
            provider = providers.get(0);
            maxAmount += amount.get(provider) * count.get(provider);
            if (maxAmount >= products || result.size() == price.size() - 1) {
                result.add(provider);
                break;
            } else {
                result.add(provider);
            }
            providers.clear();
            n -= amount.get(provider) * count.get(provider);
        }
        for (Integer r : result) {
            sb.append(r).append(",");
        }
        sb.deleteCharAt(sb.length() - 1);
        return sb.toString();
    }
→ Ссылка