Eu tenho um conjunto de números, e quer calcular o máximo subconjunto tal que a soma de quaisquer dois de seu elementos não é divisível por um inteiro . Tentei resolver esse problema, mas encontrei a solução quadrática, que não é uma resposta eficiente. , onde é o número de elementos e é constante. Existe melhor que solução quadrática?
algorithms
efficiency
manduinca
fonte
fonte
Respostas:
De fato, existe um algoritmo de tempo linear para isso. Você só precisa usar alguns conceitos básicos da teoria dos números. Dados dois números e , sua soma é divisível para , somente se a soma de sua restante é divisível para . Em outras palavras,n1 n2 K K
O segundo conceito que você precisa considerar é que, a soma de dois números é , apenas se um deles for estritamente menor que e o outro não for menor que . Em outras palavras,r1≠r2 K K/2 K/2
O terceiro conceito que você precisa considerar é que, se a soma dos dois números for , ambos se desviarão de por um certo , ou seja,r1≠r2 K ⌈K/2⌉−1 k≤⌈K/2⌉
Portanto, para evey no terceiro conceito, você precisa colocar ou no conjunto de soluções, mas não os dois. Você pode colocar um dos números que são realmente divisíveis por e, se for par, você poderá adicionar apenas um número cujo restante seja .k r1 r2 K K K/2
Portanto, aqui está o algoritmo.
Dado um conjunto , vamos encontrar o conjunto de soluçõesN={n1,n2,⋯,nN} S,
O algoritmo é bastante longo, mas a ideia é muito simples.
fonte
Considere um conjunto S de tamanho n contendo todos os números naturais distintos. Temos que formar o subconjunto máximo desse conjunto. Usamos uma propriedade de módulo básico e adicionamos algumas deduções para resolver o problema. Espero que seja útil para todos vocês.
Para quaisquer dois números naturais N1 e N2: (N1 + N2) mod (K) = (R1 + R2) mod (K) em que R1 = N1modK e R2 = N2% K. 1. Se nós (N1 + N2) modK = 0, isso significa (R1 + R2)% K = 0. 2. Isso significa que R1 + R2 deve ser igual a K, 2K, 3K .... 3. Mas R1 fica entre 0 e K-1 e R2 também, o que significa que sua soma não pode exceder K-1 + K-1 = 2 (K-1). 4. De 2 e 3, podemos concluir que R1 + R2 deve ser igual a K. 5. Além disso, se R1 + R2 = K significa que ambos devem ser iguais a K / 2 (somente possível se K for par) ou um deles deve ser menor que o piso [K / 2] e outro maior que o mesmo. 6. Suponha que R1 = T e R2 = KT, se pegarmos qualquer número N1 de S cujo restante é R1 e qualquer número N2 de S cujo restante é R2, sua soma será divisível por K. Portanto, o subconjunto Solução pode ter aqueles números com o restante R1 ou aqueles com o restante R2, mas não ambos.
Agora, suponha que construamos uma matriz R do tamanho K com o índice 0 a K-1. O elemento em cada índice indica o número de números no conjunto S com o restante (na divisão com K) igual ao número do índice. Não podemos ter mais de 2 números com o restante 0, pois sua soma seria divisível por K; portanto, devemos inicializar nosso contador com min (R [0], 1). Para T = 1 a T
O código para o mesmo algoritmo em C ++ é como mostrado abaixo:
fonte
Tentei traduzir para código C #, o primeiro a contar apenas o tamanho da matriz de subconjuntos e o outro incluindo o subconjunto inteiro (hash).
Contagem:
Com subconjunto:
fonte