![]() |
1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code].
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!
![]() |
S_lip |
![]()
Сообщение
#1
|
Новичок ![]() Группа: Пользователи Сообщений: 29 Пол: Мужской Реальное имя: B1-66ER Репутация: ![]() ![]() ![]() |
Здравствуйте!
Вот такая задачка: Дана упорядоченная последовательность N чисел. (2<=N<=200). Каждое число больше 0, но меньше 30000. Нужно из этого ряда найти два набора чисел, величины которых должны быть равны и минимальны. Гарантируется, что эта величина будет меньше 100000. Эту величину нужно выписать. Примеры: Дано: 1 2 3 4 5. Группы чисел: 1 2 и 3. Ответ: 3. Дано: 1 2 5 5 8 10 102. Группы чисел: 5 и 5. Ответ: 5. Дано: 2 3 4 5. Группы чисел: 2 3 и 5. Ответ: 5. Дано: 1 3 5 7 13 21. Группы чисел: 1 7 и 3 5. Ответ: 8. Дано: 1 2 5 8 14. Группы чисел: 1 2 5 и 8. Ответ: 8. Вот я придумал вот такое решение: http://img401.imageshack.us/img401/500/20308125la9.png const Программа перебирает все возможне пары сначало с участием первого числа. Если сумма этих пар больше 100000, а равные величины так и не найдены, то перебирает все возможные пары с участием второго числа и т.д. Это решение кушает очень много памяти и при большом N вылетает. Возможно, есть более элегантное и правильное решение? =) |
![]() ![]() |
Michael_Rybak |
![]()
Сообщение
#2
|
Michael_Rybak ![]() ![]() ![]() ![]() ![]() Группа: Модераторы Сообщений: 1 046 Пол: Мужской Реальное имя: Michael_Rybak Репутация: ![]() ![]() ![]() |
Его решение оптимально, поэтому твое в лучшем случае имело бы лучшую константу, и такую же асимптотику.
Цитата Сам бы делал по-другому и совершенно неочевидно, что это было бы оптимальнее. Очевидно, потому что твое - экспоненциальное, его - полиномиальное. Цитата Решения, честно говоря, не понял. Смотри. Как бы мы не выбирали числа для первой и второй суммы, мы никогда не вылезем за 100000 ни в одной из сумм (если вылазим, можно игнорировать такую выборку). Пусть мы кладем гири на весы, а не даем деньги детям (мне так удобнее). Заведем массив can_achieve_difference[-100000 .. 100000] of boolean, заполним его false'ами. Теперь по очереди решим следующие подзадачи: Какие разницы между левой и правой чашей можно получить, если у нас есть только первая гирька? Только первые две? Только первых три? И т.д. Чтобы узнать, какие разницы можно получить, используя только первые k+1 гирек (но не обязательно все k+1, конечно), нужно (k+1)-ю гирьку Х добавить ко всем найденым на данный момент разницам, и отнять от всех найденых разниц, а также учесть разницы Х и -Х. // схематически Как только can_achieve_difference[0] станет равен true, это будет означать, что решение существует. Такой подход не учитывает, что нас интересует минимальная сумма весов гирек, и не дает возможности восстановить найденое решение. Чтобы это учесть, нужно хранить не только true/false, а еще и минимальный вес и последнюю использованную гирьку. |
![]() ![]() |
![]() |
Текстовая версия | 20.07.2025 6:47 |