Maximale Teilmenge paarweise nicht durch teilbar


8

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.K
K<100,N<10000NK


Können Sie Ihre Lösung beschreiben? Sind Sie sicher, dass es eine bessere Lösung gibt? Hat die Bearbeitung Ihre Absichten bewahrt?
Böse

Unter diesem Link finden Sie einige Lösungen .
Gadheyan .ts

@ Gadheyan.ts Das von Ihnen erwähnte Problem ist ein ganz besonderer Fall dieses Problems. In diesem Problem hat die gegebene Menge von Zahlen die Form von , während wir hier eine beliebige Menge von Zahlen haben. Das von Ihnen erwähnte Problem kann in gelöst werden . O ( 1 ){1,2,,N}O(1)
Orezvani

Antworten:


13

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.n1n2KK

K(n1+n2)        K((n1 mod K)+(n2 mod 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 / 2r1r2KK/2K/2

r1+r2=K      r1<K/2, r2K/2      (r1r2, w.l.g. r1<r2).

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 r1r2KK/21kK/2

r1+r2=K      kK/21   such that   r1=K/21k, r2=K/2+k.

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 / 2kr1r2KKK/2

Daher ist hier der Algorithmus.

Wenn eine Menge ist, finden wir die LösungsmengeS ,N={n1,n2,,nN}S,

  1. Betrachten SieR={r1=(n1 mod K),r2=(n2 mod K),,rN=(nN mod K)}
  2. S
  3. für zu :K / 2 - 1k1K/21
  4. if :count(R,k)count(R,Kk)
  5. addiere alle zu , so dassS r i = kniSri=k
  6. else:
  7. addiere alle zu , so dassS r i = K - kniSri=Kk
  8. füge nur ein zu so dass // falls vorhandenS r i = 0niSri=0
  9. wenn ist:K
  10. füge nur ein , so dass // falls vorhandenS r i = K / 2niSri=K/2
  11. AusgabeS

Der Algorithmus ist ziemlich lang, aber die Idee ist sehr einfach.


@ DW Ich nahm an, dass . Ich habe diese Annahme absichtlich gemacht, um gerade Zahlen zu vermeiden; Ich habe folgendes hinzugefügt: "wlg "r 1 < r 2r1r2r1<r2
orezvani

@DW Gerade Zahlen werden nicht vollständig vermieden. Wenn Sie fortfahren, werden Sie sehen, warum ich ein solches Konzept / Lemma aufgestellt habe. Grundsätzlich sind wir für eine gerade Zahl , wenn der Rest einiger s genau , nur an einem dieser s interessiert (wenn wir mehr als eins setzen, verletzen wir die Bedingung der Frage). Deshalb habe ich alle diese s mit dieser Bedingung separat behandelt. n i K / 2 n i n iKniK/2nini
Orezvani

@ DW Ich habe wlg für . Ich denke, das war wirklich unnötig, aber ich habe es nur aus Gründen der Konventionen ausgedrückt. r1<r2
Orezvani

OK, ich verstehe was du jetzt meinst! Danke für die Erklärung.
DW

1

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:

#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;


int main() {

    int n,k;
    cin>>n>>k;
    vector <int> a(n);
    vector <int> r(k,0);
    for(int i=0;i<n;i++)
    {   
        cin>>a[i];
        r[a[i]%k]++;
    }
    int ctr=min(1,r[0]);
    for(int a=1;a<(k/2+1);a++)
        {
            if(a!=k-a)
                ctr+=max(r[a],r[k-a]);
        }
    if(k%2==0&&r[k/2]!=0)
        ctr++;
    cout<<ctr;
    return 0;
}

Könnten Sie Ihren Code in Pseudocode übersetzen?
Böse

1. Lesen Sie k, n 2. Machen Sie zwei Arrays A und R der Größe n und k 3. i = 0, ctr = 0, a = 1 4. während (i <n) A [i] R [A [lesen i]% k] ++ i = i + 1 während 5. ctr = Minimum (1, R [0]) 6. während (a <k / 2 + 1) tun, wenn (a! = ka) ctr = ctr + Maximum (R [a], R [ka]) endif a = a + 1 bis 7. wenn (k ergibt 0 Rest, wenn durch 2 geteilt und R [k / 2] nicht Null ist) ctr = ctr + 1 8. print ctr 9. Ende
Dhruva Bhagdikar

Ich habe in der Post mit edit gemeint, entschuldige mich für die Unannehmlichkeiten und danke für den Pseudocode.
Evil

0

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:

static int nonDivisibleSubset(int k, int[] S)
{
    var r = new int[k];

    for (int i = 0; i < S.Length; i++)
        r[S[i] % k]++;

    int count = Math.Min(1, r[0]); 

    if (k % 2 == 0 && r[k / 2] != 0) 
        count++;                                    

    for (int j = 1; j <= k / 2; j++) 
    {                                                         
        if (j != k - j)
            count += Math.Max(r[j], r[k - j]);
    }

    return count;
}

Mit Teilmenge:

static int nonDivisibleSubset(int K, int[] S)
{
    var r = new HashSet<int>();
    var d = S.GroupBy(gb => gb % K).ToDictionary(Key => Key.Key, Value => Value.ToArray());

    for (int j = 1; j <= K / 2; j++)
    {
        var c1 = d.GetValueOrDefault(j, new int[0]);
        var c2 = d.GetValueOrDefault(K - j, new int[0]);

        if (c1.Length == c2.Length) continue;

        r.UnionWith(c1.Length > c2.Length ? c1 : c2);
    }

    if (d.ContainsKey(0))
        r.Add(d[0].Max());

    if (K % 2 == 0 && d.ContainsKey(K / 2))
        r.Add(d[K / 2].Max());

    return r.Count;
}

1
Dies ist keine Codierungsseite.
Yuval Filmus

Ist das eine Mathe-Seite?
BigChief

Der genaue Umfang der Website ist schwer zu definieren. Sie können sich umschauen, um zu sehen, welche Fragen geschlossen werden und welche nicht.
Yuval Filmus

Meine Absicht war es, dem bereits veröffentlichten Code mehr Tiefe zu verleihen. Auch der letztere Codeblock gibt eine Teilmenge zurück, die die gesamte Teilmenge explizit maximiert, anstatt nur die Größe der Teilmenge zurückzugeben. Hoffentlich ist dies hilfreich für alle, die versuchen, das vorliegende Problem zu verstehen. Ich hoffe auch, Feedback zur Richtigkeit zu erhalten. Buchungscode oder mathematische Gleichungen haben eine gewisse Äquivalenz?
BigChief

Postleitzahl wird normalerweise verpönt. Wir bevorzugen Pseudocode oder eine Textbeschreibung.
Yuval Filmus
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.