Кількість мультисетів, таким чином, що кожне число від 1 до може бути однозначно виражено у вигляді суми деяких елементів мультисети


11

Моя проблема. З огляду на , я хочу , щоб підрахувати число дійсних мультимножинами S . Багатомісний S є дійсним, якщоnSS

  • Сума елементів S дорівнює n , а
  • Кожне число від 1 до n може бути виражена однозначно як сума деяких елементів S .

Приклад. Наприклад, якщо n=5 то {1,1,1,1,1},{1,2,2},{1,1,3} дійсні.

Однак S={1,1,1,2} недійсний, тому що 2 можуть бути утворені як {1,1} і {2} (тобто 2 можуть бути виражені як 2=1+1 і 2=2 ), тому друга умова не виконується. Аналогічно 3 можуть бути утворені за допомогою {2,1} і {1,1,1} .

S={1,2,4 } також недійсний, оскільки всі числа від 1 до 5 можна однозначно скласти, але сума елементів S не дорівнює 5 .


Я досить довго намагався знайти хороший алгоритм для цієї проблеми, але не можу її вирішити. Це з кодексу . Я бачив деякі подані рішення, але все ще не міг знайти логіку для вирішення проблеми. ПРИМІТКА . Час запитання становить 10 секунд і n<109

Для мультисету я буду використовувати позначення S={(a1,c1),(a2,c2)...} ai<aj якщо i<j , що означає, що ai трапляється ci разів у мультисети S.

До цього часу я зробив деякі висновки

  • Першим елементом необхідного відсортованого мультисети має бути 1
  • Нехай - це набір, що слідує за двома властивостями, тоS={1,a2ak}|a1a2akr<k  ar+1=ar or (i=0rai)+1
  • Нехай , де трапляється разів, випливає необхідним властивостям, то з наведеного вище висновку можна сказати, що і якщо . Доведення:S={(1,c1),(a2,c2)(ak,ck)}|a1a2akaicii ai|n+1ai|ajj>i
    ai+1=(aici+ai1)+1ai|ai+1
  • Тепер розглянемо тобто всі наступні числа після 1 будуть кратними . Тож нехай можливим підрахунком такого мультисета, тоді де я підсумовую всі можливі числа ( ). Іншими словамиS={1,11d1,d,dd,dm1,dm1dm1,dm2,dm2dm2,}df(n)f(n)=d|n+1,d1f(n(d1)d)1s=d1f(n1)=g(n)=d|n,dng(d)

Нарешті, моя проблема зводиться до цього - знайти ефективно, щоб він не перевищував обмеження в часі.g(n)


2
Ви перевірили, чи доцільно просити інших публічно публікувати рішення та алгоритми для практичних проблем? Здається, що FAQ FAQ про Codechef очікує, що рішення не публікуватимуться публічно (за винятком деяких дуже основних проблем). Чи може розміщення рішення тут "псує" проблеми практики для інших, чи це вважається нормальним? Я не знайомий з нормами та етикетом спільноти Codechef.
DW

Я не знайшов нічого, пов’язаного з тим, щоб не розміщувати питання у відкритому доступі у faq, і це обмеження стосується поточних проблем конкурсу, а не проблеми практики.
справедливість ліга

1
@DW Я не думаю, що вони будуть проти, якщо ми обговоримо проблеми, які не є з постійних конкурсів.
Раві Упадхей

1
Ви шукаєте кількість розділів вхідного номера. Я пропоную вам провести кілька досліджень, використовуючи це словесне слово.
Рафаель

2
@Raphael, я згоден, плакат повинен прочитати ці методи. Це не зовсім та сама проблема - перша умова афіші вимагає, щоб це був розділ, але друга умова встановлює додаткові обмеження (для унікального внесення змін ) - але можливо застосувати ті самі методи, що використовуються для підрахунку числа розділів, з деякими модифікаціями, що стосуються додаткової вимоги.
DW

Відповіді:


2

Ось, що найшвидше рішення . Це дійсно обчислюється ваша функція Дано , ми її факторируємо (див. нижче), а потім обчислити всі чинники (див. нижче) у певному порядку, таким чином, що має на увазі (властивість P). Тепер обчислюємо за формулою, перебираючи фактори в заданому порядку. Властивість P гарантує , що , коли ми обчислюємо , ми вже обчислені для всіх нетривіальних факторів в . Також є оптимізація (див. Нижче).

g(n)=dnd<ng(d),g(1)=1.
nf1,,fmfi|fjijgg(d)g(e)ed

Більш докладно ми переходимо через фактори по порядку, і для кожного фактора знаходимо всі його нетривіальні фактори, перевіряючи, який з ділить .fif1,,fi1fi

Факторинг: попередня обробка: ми робимо список усіх праймерів нижче за допомогою сита Ератостена. З огляду на , ми просто використовуємо пробний поділ.109n

Генерація всіх факторів: це робиться рекурсивно. Припустимо, . Біжимо Вкладені цикли , і вихід . Можна довести властивість P за допомогою індукції.n=p1k1ptkttl1{0,,k1},,lt{0,,kt}p1l1ptlt

Оптимізація: оскільки програма запускається на декількох входах, ми можемо використовувати пам'ятку, щоб заощадити час на різних входах. Ми запам'ятовуємо лише невеликі значення (до ), і це дозволяє нам зберігати всі запам'ятовані значення в масиві. Масив ініціалізується з нулями, і тому ми можемо сказати, які значення вже відомі (оскільки всі обчислені значення є позитивними).105


Якщо основна факторизація - , то залежить лише від , а фактично лише від відсортованої версії цей вектор. Кожне число нижче має щонайменше простих коефіцієнтів (з повторенням), і оскільки , здається, що можливо обчислити (а точніше, ) для всіх їх рекурсивно. Це рішення може бути швидшим, якби було багато різних входів; як є, їх є максимум .n+1p1k1,,ptktf(n)(k1,,kt)10929p(29)=4565fg10

Можливо також, що ця функція, зіставляючи розділи до відповідного , має явну аналітичну форму. Наприклад, , задається A000670 , а задано A005649 або A172109 .gg(pk)=2k1g(p1pt)g(p12p2pt)


1

Гаразд, тож у вас є відношення повторення для (див. Кінець свого запитання).g()

На даний момент здається, що природним підходом було б записати рекурсивний алгоритм для обчислення і застосувати запам'ятовування, щоб ви не обчислювали більше одного разу. Іншими словами, коли ви обчислюєте , ви зберігаєте його у хеш-таблиці, яка відображає ; якщо вам потрібно буде знову знати в майбутньому, ви можете переглянути його в хеш-таблиці.g(n)g(i)g(i)ig(i)g(i)

Для цього потрібен факторинг , але існують ефективні алгоритми для факторингу при .nnn109

Ви також можете шукати послідовність в он-лайн енциклопедії цілих послідовностей . Якщо ви знайдете послідовність у їхній енциклопедії, іноді вони нададуть додаткову корисну інформацію (наприклад, ефективні алгоритми для обчислення послідовності). Це, мабуть, може вивезти із задоволення речі.g(1),g(2),g(3),g(4),g(5),


0

Ось підказка для початку роботи. Застосуйте стандартні алгоритми динамічного програмування для перерахування набору розділів цілого числа та додайте певну логіку, щоб перевірити, який із них дозволяє здійснити унікальні зміни шляхом ітеративної перевірки всіх сум, внесення змін та перевірки унікальності.

У трохи більш докладно: Припустимо , у вас є мультімножество . З огляду на число з , як ви могли ідентифікувати підмультисета який підсумовує ? Як ви могли перевірити, чи унікальний цей підмультисет? Спробуйте адаптувати стандартні методи динамічного програмування для внесення змін . (Див. Також це питання .)Si1inSi

З огляду на мультисети , як ви могли перевірити, чи відповідає він другій умові, тобто чи кожне число від 1 до може бути однозначно виражене сумою підмультисета (унікальна умова внесення змін)? Це повинно бути досить легко, якщо ви вирішили попередній.SnS

нехай позначає перелік мультисетів, які відповідають обом вашим умовам. Якщо ви знали , як би ви могли використовувати цю інформацію для побудови ? Тут ви можете скоригувати стандартні методи динамічного програмування для перерахування розділів цілого числа.P(n)P(1),P(2),,P(n)P(n+1)


Ось підхід, який, мабуть, буде кращим.

Припустимо, - мультисет, який задовольняє обидві ваші умови (для ). Як ми можемо розширити його, щоб отримати багатосезонний який має ще один елемент? Іншими словами, як ми можемо визначити всі способи додати ще один елемент до , щоб отримати новий багатосезонний який задовольняє обидві ваші умови (для деяких )?SnTSTn

Відповідь: якщо можна виразити у вигляді суми деяких елементів , то немає сенсу в додаванні його в : що може викликати порушити умова єдиності. Отже, ми можемо перерахувати всі цілі числа які не можуть бути виражені сумою деяких елементів ; кожне з них - це те, що потенційно може бути додано до щоб отримати новий багатосезонний який задовольнятиме обом умовам (для деяких інших ).xSSTxSSTn

Крім того, можна перерахувати, які цілі числа можуть бути виражені сумою деяких елементів , а які не можуть, використовуючи динамічне програмування. Ви будуєте двовимірний масив булевих, де є істинним, якщо є спосіб виразити ціле число як суму деякої частини Перші елементи ( можуть бути використані лише перші елементи ; де відсортовано, тому та ). Зауважимо, щоSA[1|S|,1n]A[i,j]jiSiSSS={s1,s2,,sk}s1s2skA[i,j]можна обчислити, використовуючи значення : зокрема, якщо , або іншому випадку. Це дозволяє визначити всі числа , які є кандидатами для додавання в .A[1i1,1j1]A[i,j]=A[i1,j]A[i1,jsi]j>siA[i,j]=A[i1,j]S

Далі, для кожного розширення кандидата з (отриманого додаванням одного елемента до ), ми хочемо перевірити, чи задовольняє обом умовам. Нехай позначає суму елементів і сума елементів . Нам необхідно перевірити , чи відповідає чи кожне ціле число в інтервалі можна виразити у вигляді суми деяких з елементів . Це теж можна вирішити за допомогою динамічного програмування, використовуючи стандартні алгоритми для внесення змін. (Насправді, якщо у вас ще є масивTSSTnSnTn+1,n+2,,nTAЗгадане вище, ви можете легко розширити його трохи, щоб вирішити цю проблему: ми робимо це масив , продовжуємо заповнювати всі додаткові записи та переконайтесь, що - все вірно.) Отже, тепер ми можемо перерахувати всі багатонаціональні які розширюються одним елементом, який задовольняє обом умовам.A[1|T|,1n]A[|T|,n+1],A[|T|,n+2],,A[|T|,n]TS

Це негайно пропонує алгоритм перерахувати всі мультисети які задовольняють вашій умові, для всіх до деякої межі, скажімо, . У нас буде масив , де зберігає всі мультисети які дорівнюють 5, і, як правило, зберігає набір усіх мультизадач що дорівнює .Snn20P[120]P[5]SP[n]Sn

Далі ми можемо ітераційно заповнити . Почніть з налаштування щоб містити лише один мультисет . Далі для кожного (рахуючи від 1 до 20), для кожного перераховуйте всі можливі розширення of (використовуючи вищевикладені методики), нехай позначає суму елементів , і вставте в якщо його вже немає і якщо .P[n]P[1]{1}nSP[n]TSnTTP[n]n20

Це має бути досить виконано. Удачі! Веселіться! Опрацювання деталей буде хорошим навчанням в динамічному програмуванні.


Я не можу перерахувати всі цілі розділи, оскільки це буде експоненціальним. Я відредагував це питання і включив діапазон і деякі свої думки, але все ще я затримався. Можливо, ви можете допомогти. n
справедливість ліги
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.