Форум программистов, компьютерный форум, киберфорум
Алгоритмы
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/7: Рейтинг темы: голосов - 7, средняя оценка - 5.00
0 / 0 / 0
Регистрация: 18.09.2013
Сообщений: 24

Длиннейшая цепочка

11.08.2015, 16:22. Показов 1580. Ответов 17
Метки нет (Все метки)

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

Входные данные

Первая строка ввода содержит количество тестов t (1 ≤ t ≤ 35). Каждая из следующих t строк содержит количество элементов множества n (1 ≤ n ≤ 17) и n целых положительных чисел, каждое – от 1 до 109 включительно.

Выходные данные

Выведите t строк вида “Case #A: B”, где A – номер теста (начиная с 1), B – искомая величина для данного теста.
Есть идея сделать с помощью рекурсии, но слишком долго. Потом решился через графы но не могу довести до ума:

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
 
int used[20];
int m[20][20], kol[20];
int maxn = 0, k = 0;
int c;
 
void DFS(int v) {
    //cout << v << endl;
    used[v] = 1;
    k += 1;
    if(k > maxn)
        maxn = k;
    for(int i = 0; i < c; ++i) {
        if(!used[i] && m[v][i] == 1 && kol[v] <= 1) {
            kol[i] += 1;
            kol[v] += 1;
            DFS(i);
 
        }
    }
}
 
int main() {
    ios_base::sync_with_stdio(0);
    int n; cin >> n; //multiple test cases
 
    for(int z = 1; z <= n; ++z) {
        long a[20];
        memset(m, 0, sizeof(m));
        memset(used, 0, sizeof(used));
        memset(kol, 0, sizeof(kol));
 
        maxn = 0, k = 0;
        cin >> c;
 
        for(int i = 0; i < c; ++i) //array of numbers
            cin >> a[i]; 
 
        int d[20];
        memset(d, 0, sizeof(d));
        for(int i = 0; i < c; ++i) {
            for(int j = 0; j < c; ++j) {
                if( (a[i] % a[j] == 0) || (a[j] % a[i] == 0) ) {
                    m[i][j] = m[j][i] = 1; // Creating 2D array
                    d[i] += 1;
                }
            }
        }
 
 
        for(int i = 0; i < c; ++i) {
            k = 0;
            if(!used[i])
                DFS(i);
            if(k > maxn) //Finding max bounded graph
                maxn = k;
        }
        cout << "Case #" << z << ": ";
        cout << maxn << endl;
 
    }
}
Код через графы
Может есть специальный алгоритм. Заранее благодарю за помощь.
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
11.08.2015, 16:22
Ответы с готовыми решениями:

Цепочка из N (2-3 тысячи шт примерно) костяшек домино
Буду рад, если натолкнете на мысль в какую сторону копать по поиску оптимизированного алгоритма для решения. Стандартный рекурсивный...

Цепочка локальная машина - github - хостинг
Давно витает мысль в голове, интернет хранит молчанье... Делаю сайт на локальной машине Выгружаю на github А когда готово,...

Появилась новая цепочка коммитов после reword
История без ветвления, локальная. Гит использую в ПХПШторме. Сделал reword старого коммита и вместо старой ветки получит новую с...

17
1967 / 823 / 114
Регистрация: 01.10.2012
Сообщений: 4,832
Записей в блоге: 2
12.08.2015, 10:31
Не понял смысл. Ну вот допустим "перестало делиться", напр
...3, 5...
Ну и все, текущая цепочка закончена, остается только начать новую с пятерки. Какой же здесь выбор?
0
Модератор
Эксперт функциональных языков программирования
3134 / 2281 / 469
Регистрация: 26.03.2015
Сообщений: 8,877
12.08.2015, 12:09
Дано множество чисел. Они не выстроены в цепочку.
Наша цепочка обрывается, когда ни одно из оставшихся "не делится".
1
0 / 0 / 0
Регистрация: 18.09.2013
Сообщений: 24
12.08.2015, 13:06  [ТС]
Shamil1, Можно поподробнее? Например цепочка 1,1,3,7,15

Добавлено через 1 минуту
Igor3D, Цепочку можно перестраивать.

Добавлено через 5 минут
Igor3D, Допустим цепочка: 1,2,3. Перестраиваем в 3,1,2.
0
1967 / 823 / 114
Регистрация: 01.10.2012
Сообщений: 4,832
Записей в блоге: 2
12.08.2015, 13:46
Ага, понял, спасибо. Впечатление что это должно быть известно в теории графов: требуется найти "максимально длинный путь" между любыми 2-мя вершинами. Здесь читать надо
0
Модератор
Эксперт функциональных языков программирования
3134 / 2281 / 469
Регистрация: 26.03.2015
Сообщений: 8,877
12.08.2015, 16:09
Цитата Сообщение от Igor3D Посмотреть сообщение
Впечатление что это должно быть известно в теории графов: требуется найти "максимально длинный путь" между любыми 2-мя вершинами.
Да, именно так.
Предполагаю, что это поиск в глубину с отсечением, и сначала выбираем наиболее перспективные варианты (чтобы сразу найти хорошее решение и рано отсекать плохие ветки).

Добавлено через 2 минуты
В качестве наиболее перспективных вариантов я бы попробовал узлы с наибольшим количеством рёбер.
0
0 / 0 / 0
Регистрация: 18.09.2013
Сообщений: 24
12.08.2015, 17:52  [ТС]
Shamil1, Igor3D, Может можно использовать Гамильтонов цикл? Что-то похоже вроде.
0
1967 / 823 / 114
Регистрация: 01.10.2012
Сообщений: 4,832
Записей в блоге: 2
13.08.2015, 08:26
Цитата Сообщение от Csharper@ Посмотреть сообщение
Может можно использовать Гамильтонов цикл? Что-то похоже вроде.
Не годится, то обход всех вершин, а здесь такого условия нет. Читайте дальше и держите нас в курсе
0
Модератор
Эксперт функциональных языков программирования
3134 / 2281 / 469
Регистрация: 26.03.2015
Сообщений: 8,877
13.08.2015, 10:58
Я вчера попробовал обход в глубину без оптимизаций. На случайных числах при указанных в условии размерах работает очень быстро.
0
0 / 0 / 0
Регистрация: 18.09.2013
Сообщений: 24
13.08.2015, 12:12  [ТС]
Shamil1, В системе проверяли?
0
Модератор
Эксперт функциональных языков программирования
3134 / 2281 / 469
Регистрация: 26.03.2015
Сообщений: 8,877
13.08.2015, 14:59
Csharper@, нет, не проверял
По идее простого обхода в глубину без оптимизации не должно хватать. Иначе, нет смысла в такой задаче.
0
1967 / 823 / 114
Регистрация: 01.10.2012
Сообщений: 4,832
Записей в блоге: 2
13.08.2015, 17:45
А куда же делись любители "тыц ссылкой"? (отот кучерявый и др). Здесь это было бы очень к месту.

Eсли "длиннейший путь между 2 заданными" - то все очень просто. Также "длиннейший от заданной до всех возможных". Но из этого, к сожалению, ничего не следует. Напр путь (a...b....c) не означает что найденный участок (b..c) длиннейший (между b и с). Гуглить надо, здесь сходу не прорваться
0
0 / 0 / 0
Регистрация: 18.09.2013
Сообщений: 24
14.08.2015, 21:10  [ТС]
Никто не знает?
0
 Аватар для Rasul96
27 / 27 / 6
Регистрация: 04.04.2013
Сообщений: 137
Записей в блоге: 1
14.08.2015, 21:17
Лучший ответ Сообщение было отмечено Csharper@ как решение

Решение

Csharper@, Вы правы здесь используем динамическое программирование и битовые маски.

Вот код:

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
 
#define MAXN 18
 
bool graph[MAXN][MAXN], hasPath[131073][18];
long d[MAXN], n;
 
//Функция для нахождения однерок в битовом представлении числа. NumberOfSetBits()
 
int getLongestPath(int from, int to) {
 
for(int i = 0; i <= from; ++i)
hasPath[1 << i][i] = true;
 
for (int mask = 0; mask < (1 << n); mask++)
for (int last = 0; last < n; last++)
for (int curr = 0; curr < n; curr++)
if (graph[last][curr] && (mask & (1 << curr)) == 0)
hasPath[mask | (1 << curr)][curr] |= hasPath[mask][last];
 
int result = 0;
for (int mask = 0; mask < (1 << n); mask++) {
 
for(int i = 0; i < n; ++i) {
if (hasPath[mask][i]) {
result = max(result, NumberOfSetBits(mask));
}
}
 
}
 
return result;
}
 
 
 
int main() {
ios_base::sync_with_stdio(0);
int c;
cin >> c;
 
for(int z = 1; z <= c; ++z) {
memset(graph, 0, sizeof(graph));
cin >> n;
int maxn = 0;
for(int i = 0; i < n; ++i)
cin >> d[i];
for(int i = 0; i < n; ++i) {
for(int j = 0; j < n; ++j) {
if( i != j && ( (d[i] % d[j] == 0) || (d[j] % d[i] == 0) )) {
graph[i][j] = 1;
}
}
}
 
memset(hasPath, 0, sizeof(hasPath));
maxn = max(maxn, getLongestPath(n - 1, 0));
 
cout << "Case #" << z << ": ";
cout << maxn << endl;
}
 
}
Вроде работает быстро.
1
0 / 0 / 0
Регистрация: 18.09.2013
Сообщений: 24
14.08.2015, 21:19  [ТС]
Rasul96, Огромное спасибо!
0
1967 / 823 / 114
Регистрация: 01.10.2012
Сообщений: 4,832
Записей в блоге: 2
15.08.2015, 07:27
Цитата Сообщение от Rasul96 Посмотреть сообщение
bool graph[MAXN][MAXN], hasPath[131073][18];
Не слабо аж для 18 вершин Это в Qt так научили разбазаривать ресурсы?

Вот кое-какая теория http://bibliofond.ru/view.aspx?id=445226. См 4.2. Хмм... пока не очень ясно с пересчетом вершин...
0
 Аватар для Rasul96
27 / 27 / 6
Регистрация: 04.04.2013
Сообщений: 137
Записей в блоге: 1
15.08.2015, 09:54
Igor3D, Да, можно было динамически создавать каждый раз. Но так как N <= 17 и 2^17 + 1 = 131073 то и выбрал такое значение чтобы не заморачиваться. Главное понять способ.
0
15.08.2015, 14:13

Не по теме:

а что такое Qt?

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
15.08.2015, 14:13
Помогаю со студенческими работами здесь

Цепочка
Предлагаю игру: участник топика отвечает на вопрос предыдущего участника, затем придумывает свой вопрос (можно ситуацию). Далее по...

Цепочка записей
Создать в динамической памяти цепочку записей, содержащих координаты точек траектории «квадрат с выгнутыми наружу сторонами». Запустить...

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

Навигационная цепочка
Подскажите код навигационной цепочки. Спасибо.

Цепочка из скриптов
Есть три скрипта на php. Запрос идёт от 1 к 2, зате к 3 и обратно по цепочке возвращается к 1. Подскажите как это реализовать? Можно ли...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Новые блоги и статьи
Использование SDL3-callbacks вместо функции main() на Android, Desktop и WebAssembly
8Observer8 24.01.2026
Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а привычная функция main(). . .
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
Модель сукцессии микоризы
anaschu 24.01.2026
Решили писать научную статью с неким РОманом
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь(не выше 3-го порядка) постоянного тока с элементами R, L, C, k(ключ), U, E, J. Программа находит переходные токи и напряжения на элементах схемы классическим методом(1 и 2 з-ны. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru