Разделочная доска algo

1

У меня прямоугольная доска размером MxN, которую нужно разрезать на квадратные куски размером 1x1. Каждый из этих квадратов имеет некоторое значение, а стоимость резки - это сумма значений всех квадратов, участвующих в разрезе. Я хочу найти минимально возможную стоимость.

пример

Скажем, у нас есть плата 2x3, а значения квадратных точек указаны в виде:

2 7 5
1 9 5

Теперь, если мы сначала сделаем горизонтальный разрез, стоимость будет (2 + 7 + 5 + 1 + 9 + 5 = 29), и мы получим две более мелкие реактивные панели:

2 7 5 и 1 9 5

Затем мы сокращаем 1,9 и 5 (стоимость = 1 + 9 + 5 = 15), затем 2,7 и 5 (стоимость = 2 + 7 + 5 = 14). Итак, у нас есть следующие платы:

2 7, 5, 1 9, 5

После этого мы разрезаем 1 и 9 (стоимость = 1 + 9 = 10), затем 2 и 7 (стоимость = 2 + 7 = 9). И у нас есть следующие квадраты:

2, 7, 5, 1, 9, 5

Теперь мы остановимся, поскольку все оставшиеся peices равны 1x1.

Таким образом, общая стоимость составляет 77. Теперь это всего лишь один из способов, который дает минимальную стоимость. Существуют и другие способы разрезания платы, которые могут давать такую же или более высокую стоимость.

Итак, как я могу найти минимальную стоимость? Спасибо за помощь!

  • 0
    Что ты пробовал до сих пор?
  • 0
    Вы можете уточнить, как работает резка?
Показать ещё 4 комментария
Теги:
arrays
python-3.x
python-2.7

1 ответ

0

Это заняло у меня время, чтобы придумать, и не очень эффективно, но для маленьких головоломок это должно быть хорошо.

class Piece:
    def __init__(self, data, w, h):
        self.data = data
        self.w = w
        self.h = h

    def cut_vertically(self, x):
        a = Piece([v for i, v in enumerate(self.data) if i % self.w <= x], x + 1, self.h)
        b = Piece([v for i, v in enumerate(self.data) if i % self.w > x], self.w - x - 1, self.h)
        s = sum(self.data)
        return a, b, s

    def cut_horizontally(self, y):
        a = Piece([v for i, v in enumerate(self.data) if i < self.w * (y + 1)], self.w, y + 1)
        b = Piece([v for i, v in enumerate(self.data) if i >= self.w * (y + 1)], self.w, self.h - y - 1)
        s = sum(self.data)
        return a, b, s

    def generate_cuts(self):
        for x in range(self.w - 1):
            yield self.cut_vertically(x)
        for y in range(self.h - 1):
            yield self.cut_horizontally(y)

def scores(p):
    if p.w == 1 and p.h == 1:
        yield 0

    for a, b, s in p.generate_cuts():
        for s1 in scores(a):
            for s2 in scores(b):
                yield s + s1 + s2

p = Piece([2, 7, 5, 1, 9, 5], 3, 2)

min_score = None
for score in scores(p):
    if not min_score or score < min_score:
        min_score = score

print(score)

У него нет проверки на наличие ошибок, поэтому вы должны убедиться, что ваш Piece настроен правильно, но я надеюсь, что этого достаточно для ваших нужд.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню