Oto wskazówka na początek. Zastosuj standardowe algorytmy programowania dynamicznego do wyliczenia zestawu partycji liczb całkowitych i dodaj logikę, aby sprawdzić, który z nich pozwala na unikalne dokonywanie zmian poprzez iteracyjne sprawdzanie wszystkich sum, wprowadzanie zmian i weryfikowanie niepowtarzalności.
W nieco bardziej szczegółowo: Załóżmy, że masz multiset S . Biorąc pod uwagę liczbę i o wartości 1 ≤ i ≤ n , w jaki sposób można zidentyfikować podwielokrotność S, która sumuje się do i ? Jak mogłeś sprawdzić, czy ten subultiset jest wyjątkowy? Spróbuj dostosować standardowe techniki programowania dynamicznego do wprowadzania zmian . (Zobacz także to pytanie .)Si1≤i≤nSi
Biorąc pod uwagę multiset S , jak możesz sprawdzić, czy spełnia on drugi warunek, tj. Czy każda liczba od 1 do n może być jednoznacznie wyrażona jako suma subultiset S (unikalny warunek zmiany)? To powinno być dość łatwe, jeśli rozwiązałeś poprzedni.SnS
niech P ( n ) oznacza listę multisets, które spełniają oba warunki. Jeśli znasz P ( 1 ) , P ( 2 ) , … , P ( n ) , jak możesz wykorzystać te informacje do skonstruowania P ( n + 1 ) ? Tutaj możesz chcieć dostosować standardowe techniki programowania dynamicznego do wyliczania partycji liczb całkowitych.P(n)P(1),P(2),…,P(n)P(n+1)
Oto podejście, które prawdopodobnie będzie lepsze.
Załóżmy, że S to zbiór, który spełnia oba warunki (dla n ). Jak możemy go rozszerzyć, aby uzyskać wielosekcyjny T, który ma jeszcze jeden element? Innymi słowy, w jaki sposób możemy zidentyfikować wszystkie sposoby dodania jeszcze jednego elementu do S , aby uzyskać nowy wielosekcyjny T, który spełnia oba warunki (dla niektórych n ′ )?SnTSTn′
Odpowiedź: jeśli x można wyrazić jako sumę niektórych elementów S , to nie ma sensu dodawać go do S : spowodowałoby to, że T naruszyłby warunek wyjątkowości. Możemy więc wyliczyć wszystkie liczby całkowite x , których nie można wyrazić jako sumę niektórych elementów S ; każdy z nich jest czymś, co można potencjalnie dodać do S, aby uzyskać nowy wielosetowy T , który spełni oba warunki (dla niektórych innych n ).xSSTxSSTn
Ponadto możliwe jest wyliczenie, które liczby całkowite mogą być wyrażone jako suma niektórych elementów S , a które nie, za pomocą programowania dynamicznego. Budujesz dwuwymiarową tablicę A [ 1 … | S | , 1 ... n ] Wartości zmiennych, w których [ i , j ] jest prawdziwe, czy nie jest sposobem wyrażania całkowitą j jako sumę niektóre z pierwszych ı elementów S (tylko pierwszy ı elementów S kwalifikują się do być użyte; gdzie SSA[1…|S|,1…n]A[i,j]jiSiSSzostały sortowane, więc S = { y 1 , y 2 , ... , s k } , a s 1 ≤ s 2 ≤ ⋯ ≤ y k ). Zauważ, że A [ i , j ] może być obliczane przy użyciu wartości A [ 1 … i - 1 , 1 … j - 1 ] : w szczególności A [ i , j ]S={s1,s2,…,sk}s1≤s2≤⋯≤skA[i,j]A[1…i−1,1…j−1]= A [ i - 1 , j ] ∨ A [ i - 1 , j - s i ] jeśli j > s i lub A [ i , j ] = A [ i - 1 , j ] w przeciwnym razie. To pozwala nam zidentyfikować wszystkie numery, które są kandydatami do doliczone do S .A[i,j]=A[i−1,j]∨A[i−1,j−si]j>siA[i,j]=A[i−1,j]S
Następnie dla każdego rozszerzenia kandydat T z S (otrzymanego przez dodanie jednego elementu do S ), chcemy sprawdzić, czy T spełnia oba warunki. Niech N oznacza sumę składników S , a n ' suma elementów T . Musimy sprawdzić, czy każdą liczbę całkowitą z zakresu n + 1 , n + 2 , … , n ′ można wyrazić jako sumę niektórych elementów TTSSTnSn′Tn+1,n+2,…,n′T. To również można rozwiązać za pomocą programowania dynamicznego, przy użyciu standardowych algorytmów do wprowadzania zmian. (W rzeczywistości, jeśli nadal masz tablicę A wspomnianą powyżej, możesz łatwo ją trochę rozszerzyć, aby rozwiązać ten problem: robimy ją tablicą A [ 1 … | T | , 1 … n ′ ] , nadal wypełniamy wszystkie dodatkowych wpisów i upewnij się, że A [ | T | , n + 1 ] , A [ | T | , n + 2 ] ,AA[1…|T|,1…n′]… , A [ | T | , n ′ ] są prawdziwe.) Teraz możemy wyliczyć wszystkie multisety T, które rozciągają S o jeden element i które spełniają oba warunki.A[|T|,n+1],A[|T|,n+2],…,A[|T|,n′]TS
To natychmiast sugeruje algorytm do wyliczenia wszystkich multisetów S, które spełniają twój warunek, dla wszystkich n do pewnego związanego, powiedzmy n ≤ 20 . Będziemy mieli tablicę P [ 1 … 20 ] , w której P [ 5 ] przechowuje wszystkie multisety S, które sumują się do 5, i ogólnie P [ n ] przechowuje zbiór wszystkich multisetów S, które sumują się do n .Snn≤20P[1…20]P[5]SP[n]
Następnie możemy iteracyjnie wypełnić P [ n ] . Zacznij od ustawienia P [ 1 ] tak, aby zawierał tylko jeden multiset { 1 } . Następnie, dla każdego n (liczy się od 1 do 20), dla każdego S ∈ p [ n ] , wyliczyć wszystkich możliwych rozszerzeń T z S (z wykorzystaniem technik wyżej), niech n " oznacza sumę elementów T , i wstawić T do P [ n ′ ]jeśli nie jest już obecny, a jeśli n ' ≤ 20 .
To powinno być całkiem wykonalne. Powodzenia! Baw się dobrze! Przepracowanie szczegółów będzie dobrym ćwiczeniem do nauki w programowaniu dynamicznym.