En büyük toplam n'ye bölünebilir


16

StackOverflow bu soruyu sordum , ama burada daha uygun bir yer olduğunu düşünüyorum.

Bu algoritma giriş ders bir sorun :

Bir dizi var a ile n pozitif (dizi sıralanacak gerekmez veya elemanlar benzersiz) tamsayılar. Bir sonuçları O(n) ile bölünebilen elemanlarının büyük toplamı bulmak için algoritma n .

Örnek: a=[6,1,13,4,9,8,25],n=7 . Cevap 56 ( elementli 6,13,4,8,25)

Dinamik programlama kullanarak ve 0 , 1 , 2 , kalan en büyük toplamı depolayarak de bulmak nispeten kolaydır . . . , n - 1 .O(n2)0,1,2,...,n1

Ayrıca, dikkati bitişik bir eleman dizisiyle kısıtlarsak , kısmi toplamları modulo n depolayarak zamanında bu tür optimal diziyi bulmak kolaydır : let S [ i ] = a [ 0 ] + a [ 1 ] + + bir [ ı ] , her bir geri kalan için r büyük endeks hatırlamak j öyle ki S [ j ] rO(n)nS[i]=a[0]+a[1]++a[i]rj ve daha sonra her bir i için S [ j ] - S [ i ] olduğunu düşünürsünüz; burada j , r = S [ i ] mod n'ye karşılık gelen dizindir .S[j]r(modn)iS[j]S[i]jr=S[i]modn

Fakat genel durum için -zamanlı bir çözüm var mı? Herhangi bir öneriniz takdir edilecektir! Bunun lineer cebirle uğraşacak bir şey olduğunu düşünüyorum ama tam olarak ne olduğundan emin değilim.O(n)

Alternatif olarak, bu zamanında yapılabilir mi?O(nlogn)


2
1. Aynı soruyu Stack Overflow'a da gönderdiniz. Lütfen aynı soruyu birden fazla sitede yayınlamayın . Birden çok SE sitesinde birden çok kopya etrafında dolaşmak istemiyoruz. Kabul edilebilir bir yanıt almadıysanız, sorunuzu başka bir siteye geçiş için işaretlemek sorun olmaz, ancak lütfen aynı şeyi başka bir yere tekrar göndermeyin. 2. Bu ders kitabına veya kursa göründüğü kaynak / atıf / bağlantı verebilir misiniz? -zamanlı bir çözümün olduğundan emin misiniz ? O(n)
DW

5
Üniversitenizdeki zorluk hala açık mı? Kurs bağlantısını, kesin soruyu görmek gerçekten yararlı olacaktır ve gerçekten ve onu hazırlayanlar cevaplarını açıklayacak / yayınlayacaklarsa harika olurdu. O(n)
Evil

Dinamik programlama kullanarak ve 0,1,2, ..., n − 10,1,2, ..., n − 1 ile en büyük toplamı depolayarak O (n2) O (n2) 'de bulmak nispeten kolaydır. Lütfen bunu biraz açıklayabilir misiniz? Yalnızca bitişik öğeleri düşünürsek, ancak bitişik olmayan öğelerle de bunun üstel olmaz mıydı?
Nithish Inpursuit Ofhappiness

Yanıtlar:


4

İşte birkaç rastgele fikir:

  • Dinamik programlama algoritması, en büyük toplam yerine en küçük toplamı aramak için çevrilebilir. Sonunda, bir sıfıra uygun yerine, tüm dizinin toplamının geri kalanına uygun bir toplam arıyorsunuz. Elemanları artan sırayla işlersek, bu bazen dinamik algoritmanın tüm diziyi işlemeden önce sonlanmasına izin verir.

    Eğer k öğelerini işlersek maliyet olur . Orada değil sınırı daha düşük Q ( n log n ) biz tüm öğeleri sıralamak yok çünkü bu algoritmaya. Sadece O ( n log k ) zaman alırO(nk)kΩ(nlogn)O(nlogk) en küçük unsurları.k

  • Kümeyi larget boyutuyla önemsediğimizde, en büyük toplamı olan küme yerine, zaman. Etki alanı aralığı sınırlı olduğunda 3SUM'da yapılanlara benzer . (Not: ikili arama yapmak için tekrarlanan kareleri kullanın, aksi takdirde O ( n k ( log n ) ( log log n ) elde edersiniz )O(n(logn)2(loglogn))O(nk(logn)(loglogn))k atlanan öğelerin sayısıdır.)

  • Ne zaman kompozit olduğunu ve hemen hemen tüm kalıntılarını birinin birkaç katıdır n 'in faktörler, önemli zaman o faktörün katları olmayan kalanları odaklanarak kaydedilebilir.nn

  • Bir kalıntı rçok yaygın olduğunda veya yalnızca birkaç kalıntı olduğunda, 'buradan başlarsanız ve ilerlemeye devam ederseniz bir sonraki açık alanın izlenmesi r' bilgileri, açık noktalara atlamak için çok fazla tarama kaydedebilir saati.

  • Bir günlük faktörünü yalnızca erişilebilirliği izleyerek ve bit maskelerini (çevrilmiş dinamik algoritmada) kullanarak ve ardından hedef kalana ulaştığınızda geri izleyerek tıraş edebilirsiniz .

  • Dinamik programlama algoritması paralel olarak çalıştırılmaya çok uygundur. Her tampon yuvası için bir işlemci ile değerine inebilirsiniz . Alternatif olarak, O ( n 2 ) genişliğini kullanarak ve yinelemeli toplama yerine bölünmeyi ve fethetmeyi kullanarak , devre derinliği maliyeti tamamen O'ya ( log 2 n ) kadar inebilir .O(n)O(n2)O(log2n)

  • (Meta) Size verilen sorunun bitişik meblağlardan kaynaklandığından şüpheleniyorum . Asıl sorunla bağlantı kurduysanız, bunu doğrulamak kolay olacaktır. Aksi takdirde, "Algoritmalara Giriş" adlı bir derste atandığı göz önüne alındığında, bu sorunun ne kadar zor olduğuna çok şaşırdım. Ama belki de sınıfta bunu önemsiz yapan bir numara yaptınız.


nO(n)

2
r1r2

-1

Önerilen algoritmam aşağıdaki gibi gidiyor:

Yalnızca n'nin katları olan toplamlar eklerseniz bir toplam n ile bölünebilir.

Başlamadan önce int as anahtarına sahip bir hashmap ve değer olarak endekslerin bir listesini oluşturursunuz. Ayrıca indeksler içeren bir sonuç listesi de oluşturabilirsiniz.

Daha sonra dizi üzerinde döngü ve mod n sıfır olan her dizini sonuç listenize ekleyin. Diğer tüm dizinler için aşağıdakileri yaparsınız:

Bu dizinin n mod değerini n'den çıkarırsınız. Bu sonuç, gerekli değere sahip elemanlar için endeksleri saklayan hashsinizin anahtarıdır. Şimdi, bu dizini hashmap içindeki listeye ekleyip devam edersiniz.

Dizi üzerinde döngü bittikten sonra çıktı hesaplar. Bunu, hashmap içindeki her listeyi dizinin işaret ettiği değere göre sıralayarak yaparsınız. Şimdi hashmap'taki her çifti n'ye kadar toplarsınız. Eğer n = 7 ise hashmap'i 3 ve 4 için ararsanız, her ikisinde de bir girişiniz varsa, en büyük iki değeri alırsınız, bunları listelerinden kaldırın ve sonuç listenize ekleyin.

Son öneri: algoritmayı hala test etmedi, kaba kuvvet algoritması kullanarak buna karşı bir testcase yazın.


2
Açgözlü, doğrusal, çalışmıyor. Sadece n ile bölünebilen öğeleri ve n ile bölünebilen öğeleri, üçe ve daha fazlasına ne dersiniz? Önemsiz durumda maksimum alt küme toplamını garanti etmez. [2, 1, 8] -> maksimum toplam 9, ancak algoritmanız 3 değerini döndürüyor.
Evil

@EvilJS altyazınızla ne oldu?n2algoritması?
delta-terminatör

Bu hatayı bana gösterdiğin için teşekkürler. İyileştirme konusundaki fikrim, değeri artırarak sıralanan liste yığınlarının bir hashini yapmak ve sadece diziden bir geçiş tamamlandıktan sonra birikmeye başlamak olacaktır.
Tobias Würfl

Sıralanacak diziler dizisini kastediyorsunuz ve "hashmap"% n? Onları hala sıralamanız gerekir ve sıralamanız varsa, minimum / maksimum değer almak tamamdır, ancak yine de en kötü durumda fayda sağlamayan alt kümeyi seçmenin kaçınılmaz bir kısmı vardır. Her neyse, bazı iyileştirmeleriniz varsa, yayını düzenleyebilirsiniz?
Evil

Evet, yığınlarla ilgili oldukça hızlı bir fikirdi. Aslında sadece sıraladığınız hashmap listelerine ihtiyacınız var. İlk cevabımı düzenlemenin kibar olup olmadığından emin değildim. Ne de olsa ilk denememde bir hata yaptım.
Tobias Würfl

-2

bu DP yöntemini ( /programming/4487438/maximum-sum-of-non-consecutive-elements?rq=1 ) adresinden kullanın :

A [0..n] dizisi verildiğinde, 0..i indekslerine sahip elemanları kullanarak M (i) en uygun çözüm olsun. Sonra M (-1) = 0 (rekürrensde kullanılır), M (0) = A [0] ve M (i) = maks. (M (i - 1), M (i - 2) + A [i ]) i = 1, ..., n için. M (n) istediğimiz çözümdür. Bu O (n) . Her alt sorun için hangi seçeneğin yapıldığını saklamak için başka bir dizi kullanabilir ve böylece seçilen gerçek öğeleri kurtarabilirsiniz.

Özyinelemeyi yalnızca N ile bölünebilirse depolanacak şekilde M (i) = maks (M (i - 1), M (i - 2) + A [i]) olarak değiştirin


2
Bu işe yaramıyor - nedenini bulmanıza izin vereceğim. (İpucu: Sabit 1 dizisinde çalıştırmayı deneyin.) Ayrıca, bu problemde ardışık öğelere izin veriyoruz.
Yuval Filmus

1
Bu tamamen farklı (ve çok daha kolay) bir soruna çok iyi bir çözümdür.
Kötülük
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.