Sous-ensemble maximum par paire non divisible par


8

Je un ensemble de nombres, et souhaite calculer le sous - ensemble maximal de telle sorte que la somme de deux quelconques des éléments de ce n'est pas divisible par un nombre entier . J'ai essayé de résoudre ce problème, mais j'ai trouvé la solution quadratique, qui n'est pas une réponse efficace. , où est le nombre d'éléments et est donné constant. Y a-t-il une solution meilleure que quadratique?K
K<100,N<10000NK


Pourriez-vous décrire votre solution? Êtes-vous sûr qu'il existe une meilleure solution? Le montage a-t-il préservé vos intentions?
— Evil

Vous pouvez trouver des solutions sur ce lien .
— Gadheyan .ts

@ Gadheyan.ts le problème que vous avez mentionné est un cas très spécial de ce problème. Dans ce problème, l'ensemble de nombres donné est sous la forme de , alors qu'ici nous avons un ensemble arbitraire de nombres. Le problème que vous avez mentionné peut être résolu dans . {1,2,⋯,N}O(1)
— orezvani

Réponses:


13

En effet, il existe un algorithme de temps linéaire pour cela. Il vous suffit d'utiliser certains concepts de base de la théorie des nombres. Étant donné deux numéros et , leur somme est divisible à , que si la somme de leur reste est divisible à . En d'autres termes,n1n2KK

K∣(n1+n2)    ⟺    K∣((n1 mod K)+(n2 mod K)).

Le deuxième concept que vous devez considérer est que la somme de deux nombres est , uniquement si l'un d'eux est strictement inférieur à et l'autre n'est pas inférieur à . En d'autres termes,r1≠r2KK/2K/2

r1+r2=K   ⇒   r1<K/2, r2≥K/2      (r1≠r2, w.l.g. r1<r2).

Le troisième concept que vous devez considérer est que, si la somme de deux nombres est , ils s'écartent tous les deux de d'un certain , c'est à dire,r1≠r2K⌈K/2⌉−1k≤⌈K/2⌉

r1+r2=K   ⇒   ∃k≤⌈K/2⌉−1   such that   r1=⌈K/2⌉−1−k, r2=⌈K/2⌉+k.

Donc, pour evey dans le troisième concept, vous devez mettre ou dans l'ensemble de solutions, mais pas les deux. Vous êtes autorisé à mettre l'un des nombres qui sont réellement divisibles par et si est pair, vous ne pouvez ajouter qu'un seul nombre dont le reste est .kr1r2KKK/2

Voici donc l'algorithme.

Étant donné un ensemble , trouvons l'ensemble de solutionN={n1,n2,⋯,nN}S,

  1. ConsidéronsR={r1=(n1 mod K),r2=(n2 mod K),⋯,rN=(nN mod K)}
  2. S←∅
  3. pour à :k←1⌈K/2⌉−1
  4. si :count(R,k)≥count(R,K−k)
  5. ajoutez tous les à , de telle sorte queniSri=k
  6. sinon:
  7. ajoutez tous les à , de telle sorte queniSri=K−k
  8. ajouter un seul à telle sorte que // s'il existeniSri=0
  9. si est pair:K
  10. ajoutez un seul à telle sorte que // s'il existeniSri=K/2
  11. SortieS

L'algorithme est assez long, mais l'idée est très simple.


@DW J'ai supposé que . J'ai délibérément posé une telle hypothèse afin d'éviter les nombres pairs; J'ai ajouté ce qui suit: "wlg "r1≠r2r1<r2
— orezvani

@DW Il n'évite pas complètement les nombres pairs. Si vous continuez, vous verrez pourquoi j'ai mis un tel concept / lemme. Fondamentalement, pour le nombre pair , si le reste de certains s est exactement , alors nous ne sommes intéressés que par un de ces s (si nous en mettons plus d'un, nous violerons la condition de la question). C'est pourquoi, j'ai traité tous ces s avec cette condition séparément. KniK/2nini
— orezvani

@DW J'ai mis wlg pour . Je pense que ce n'était vraiment pas nécessaire, mais je le dis juste pour la question des conventions. r1<r2
— orezvani

OK, je vois ce que tu veux dire maintenant! Merci d'avoir expliqué.
— DW

1

Considérons un ensemble S de taille n contenant tous les nombres naturels distincts. Nous devons former le sous-ensemble maximal de cet ensemble. Nous utilisons une propriété de module de base et y ajoutons quelques déductions pour résoudre le problème. J'espère que cela vous sera utile à tous.

Pour deux nombres naturels N1 et N2 quelconques: (N1 + N2) mod (K) = (R1 + R2) mod (K) où R1 = N1modK et R2 = N2% K. 1. Si nous (N1 + N2) modK = 0, cela signifie (R1 + R2)% K = 0. 2. Cela signifie que R1 + R2 doit être égal à K, 2K, 3K .... 3. Mais R1 se situe entre 0 et K-1 et R2 aussi, ce qui signifie que leur somme ne peut pas dépasser K-1 + K-1 = 2 (K-1). 4. De 2 et 3, nous pouvons conclure que R1 + R2 doit être égal à K. 5. De plus, si R1 + R2 = K, cela signifie que les deux doivent être égaux à K / 2 (uniquement possible si K est pair) ou l'un d'eux doit être inférieur au sol [K / 2] et l'autre supérieur au même. 6. Supposons que R1 = T et R2 = KT, si nous prenons tout nombre N1 de S dont le reste est R1 et tout nombre N2 de S dont le reste est R2, alors leur somme sera divisible par K. Par conséquent, le sous-ensemble Solution peut avoir les nombres avec le reste R1 ou ceux avec le reste R2 mais pas les deux.

Supposons maintenant que nous construisons un tableau R de taille K avec un index de 0 à K-1, l'élément de chaque index indiquant le nombre de nombres dans l'ensemble S avec un reste (sur division avec K) égal au numéro d'index. Nous ne pouvons pas avoir plus de 2 nombres avec leur reste 0 car leur somme serait divisible par K donc nous devons initialiser notre compteur avec min (R [0], 1). Pour T = 1 à T

Le code du même algorithme en C ++ est le suivant:

#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;
}

Pourriez-vous traduire votre code en pseudocode?
— Evil

1. Lisez k, n 2. Créez deux tableaux A et R de taille n et k 3. i = 0, ctr = 0, a = 1 4. tandis que (i <n) lit A [i] R [A [ i]% k] ++ i = i + 1 à la fin 5. ctr = minimum (1, R [0]) 6. tandis que (a <k / 2 + 1) fait si (a! = ka) ctr = ctr + maximum (R [a], R [ka]) endif a = a + 1 pendant 7. si (k donne 0 reste lorsqu'il est divisé par 2 et R [k / 2] est non nul) ctr = ctr + 1 8. print ctr 9. Fin
— Dhruva Bhagdikar

Je voulais dire dans le post, en utilisant edit, désolé pour la gêne occasionnée et merci pour le pseudocode.
— Evil

0

J'ai essayé de traduire en code C #, le premier à ne compter que la taille du tableau de sous-ensemble et un autre comprenant l'ensemble du sous-ensemble (hachage).

Compter:

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;
}

Avec sous-ensemble:

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
Ce n'est pas un site de codage.
— Yuval Filmus

est-ce un site de mathématiques?
— BigChief

L'étendue exacte du site est difficile à définir. Vous pouvez regarder autour de vous pour voir quelles questions sont fermées et lesquelles ne le sont pas.
— Yuval Filmus

Mon intention était d'ajouter plus de profondeur au code déjà publié, le dernier bloc de code renvoie également un sous-ensemble qui maximise explicitement le sous-ensemble complet au lieu de ne renvoyer que la taille du sous-ensemble. J'espère que cela sera utile à quiconque essaie de comprendre le problème actuel. J'espère également recevoir des commentaires sur l'exactitude. Le code d'affichage ou les équations mathématiques ont une certaine équivalence?
— BigChief

Le code de publication est généralement mal vu. Nous préférons un pseudocode ou une description textuelle.
— Yuval Filmus
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.