Ich habe eine Menge von Zahlen und möchte die maximale Teilmenge so berechnen, dass die Summe von zwei beliebigen Elementen nicht durch eine ganze Zahl teilbar ist . Ich habe versucht, dieses Problem zu lösen, aber ich habe die quadratische Lösung gefunden, die keine effiziente Antwort ist. , wobei die Anzahl der Elemente ist und konstant gegeben ist. Gibt es eine bessere als eine quadratische Lösung?K < 100 , N < 10000 N K.
algorithms
efficiency
Manduinca
quelle
quelle
Antworten:
In der Tat gibt es dafür einen linearen Zeitalgorithmus. Sie müssen nur einige grundlegende Konzepte der Zahlentheorie verwenden. Bei zwei Zahlen und ist ihre Summe nur dann für teilbar , wenn die Summe ihres Restes für teilbar ist . Mit anderen Worten,n 2 K K.n1 n2 K K
Das zweite Konzept , dass Sie beachten müssen , das heißt, die Summe von zwei Zahlen ist , nur wenn einer von ihnen ist streng kleiner als und das andere ist nicht weniger als . Mit anderen Worten, K K / 2 K / 2r1≠r2 K K/2 K/2
Das dritte Konzept , dass Sie beachten müssen, ist , dass, wenn die Summe von zwei Zahlen ist , sie beide weichen von durch eine bestimmte dh K ⌈ K / 2 ⌉ - 1 k ≤ ⌈ K / 2 ⌉r1≠r2 K ⌈K/2⌉−1 k≤⌈K/2⌉
Also, für Evey im dritten Konzept, müssen Sie entweder setzen oder in der Lösungsmenge, aber nicht beide. Sie dürfen eine der Zahlen eingeben, die tatsächlich durch teilbar sind, und wenn ist, können Sie nur eine Zahl hinzufügen, deren Rest .r 1 r 2 K K K / 2k r1 r2 K K K/2
Daher ist hier der Algorithmus.
Wenn eine Menge ist, finden wir die LösungsmengeS ,N={n1,n2,⋯,nN} S,
Der Algorithmus ist ziemlich lang, aber die Idee ist sehr einfach.
quelle
Betrachten Sie eine Menge S der Größe n, die alle unterschiedlichen natürlichen Zahlen enthält. Wir müssen die maximale Teilmenge aus dieser Menge bilden. Wir verwenden eine grundlegende Modul-Eigenschaft und fügen ihr einige Abzüge hinzu, um das Problem zu lösen. Ich hoffe es ist hilfreich für euch alle.
Für zwei beliebige natürliche Zahlen N1 und N2: (N1 + N2) mod (K) = (R1 + R2) mod (K) wobei R1 = N1modK und R2 = N2% K. 1. Wenn wir (N1 + N2) modK = 0 sind, bedeutet dies (R1 + R2)% K = 0. 2. Das bedeutet, dass R1 + R2 entweder K, 2K, 3K ... sein muss. 3. Aber R1 liegt zwischen 0 und K-1 und R2 auch, was bedeutet, dass ihre Summe K-1 + K-1 nicht überschreiten kann = 2 (K-1). 4. Aus 2 und 3 können wir schließen, dass R1 + R2 gleich K sein muss. 5. Wenn R1 + R2 = K ist, bedeutet dies, dass entweder beide gleich K / 2 sein müssen (nur möglich, wenn K gerade ist) oder einer von ihnen muss kleiner als der Boden [K / 2] und einer größer als derselbe sein. 6. Angenommen, R1 = T und R2 = KT, wenn wir eine beliebige Zahl N1 von S nehmen, deren Rest R1 ist, und eine beliebige Zahl N2 von S, deren Rest R2 ist, dann ist ihre Summe durch K teilbar. Daher kann die Lösungsuntermenge entweder diese haben Zahlen mit Rest R1 oder solche mit Rest R2, aber nicht beide.
Angenommen, wir konstruieren ein Array R der Größe K mit den Indizes 0 bis K-1. Das Element in jedem Index gibt die Anzahl der Zahlen in der Menge S an, wobei der Rest (bei Division mit K) gleich der Indexnummer ist. Wir können nicht mehr als 2 Zahlen mit ihrem Rest 0 haben, da ihre Summe durch K teilbar wäre, daher müssen wir unseren Zähler mit min (R [0], 1) initialisieren. Für T = 1 bis T.
Der Code für denselben Algorithmus in C ++ lautet wie folgt:
quelle
Ich habe versucht, in C # -Code zu übersetzen, wobei der erste nur die Größe des Subset-Arrays und der andere die gesamte (Hash-) Subset enthält.
Anzahl:
Mit Teilmenge:
quelle