nで割り切れる最大の合計


16

StackOverflowでこの質問をましたが、ここがより適切な場所だと思います。

これは、アルゴリズムコースの概要からの問題です

n個の正の整数を持つ配列があります(配列を並べ替えたり、要素を一意にする必要はありません)。示唆O N で割り切れる要素の最大和見つけるためのアルゴリズムをnとanO(n)n

例: = [ 6 1 13 4 9 8 25 ] N = 7。答えは56(要素と6 13 4 8 25a=[6,1,13,4,9,8,25],n=7566,13,4,8,25

それはそれを見つけることは比較的簡単です動的プログラミングを使用して、残りで最大の和を格納0 1 2 n 1O(n2)0,1,2,...,n1

また、我々は要素の連続配列に注意を制限した場合、それはに最適なシーケンスを見つけるのは簡単だ時間、部分和を格納することによって、モジュロN:聞かせてS [ I ] = [ 0 ] + [ 1 ] + + [ I ]、各剰余のためにR最大インデックス覚えJようにS [ J ] RをO(n)nS[i]=a[0]+a[1]++a[i]rjS[j]r(modn)iS[j]S[i]jr=S[i]modn

しかし、一般的な場合のO(n)時間の解決策はありますか?どんな提案も大歓迎です!これには線形代数を扱うものがあると思いますが、何が正確かはわかりません。

あるいは、これはO(nlogn)時間で実行できますか?


2
1. Stack Overflowにまったく同じ質問を投稿しました。同じ質問を複数のサイトに投稿しないでください。複数のSEサイトに複数のコピーが浮かんでいるのは望ましくありません。受け入れ可能な答えが得られなかった場合、別のサイトへの移行のために質問にフラグを立ててもかまいませんが、同じことを他の場所に再投稿しないでください。2.これが登場した教科書またはコースへの参照/引用/リンクを提供できますか?O(n)時間のソリューションが存在することをどの程度確信していますか?
DW

5
あなたの大学の課題はまだ開かれていますか?コースへのリンク、正確な質問、そしてそれが本当にあり、それを準備した人が答えを説明/公開するなら、それは素晴らしいでしょう。O(n)
邪悪な

動的計画法を使用してO(n2)O(n2)で見つけるのは比較的簡単で、剰余0,1,2、...、n-10,1,2、...、n-1の最大合計を格納します。これについて少し詳しく教えてください。連続した要素のみを考慮した場合、これがどのようにn二乗されるかを理解できますが、非連続な要素でも同様に指数関数的ではないでしょうか?
ニシッシュインパーサーチオブ幸福

回答:


4

以下にいくつかのランダムなアイデアを示します。

  • 動的プログラミングアルゴリズムを反転して、最大の合計ではなく最小の合計を探すことができます。最終的には、ゼロに一致する1つではなく、配列全体の合計の残りに一致する合計を探します。要素を昇順で処理すると、動的アルゴリズムが配列全体を処理する前に終了することがあります。

    要素を処理した場合、コストはなります。ありますないの下限私たちはすべての要素をソートする必要はありませんので、このアルゴリズムに。最小要素を取得するには、時間しかかかりません。O(nk)kΩ(nlogn)O(nlogk)k

  • 最大の和の集合ではなく、最大の大きさの集合に関心がある場合、高速フーリエ変換ベースの多項式乗算を使用しての問題を解決できる可能性があります時間。ドメイン範囲が制限されている場合の3SUMでの処理に似ています。(注:バイナリ検索を行うために繰り返し二乗を使用します。そうしないと、が得られますは省略された要素の数です。)O(n(logn)2(loglogn))O(nk(logn)(loglogn))k

  • とき合成され、そしてほとんどすべての残りのいずれかの倍数であるの要因、かなりの時間がその要因の倍数でない余りに焦点を当てることによって保存されることがあります。nn

  • 余りrが非常に一般的である場合、または数個の余りしかない場合、「ここから開始して次のスロットまで進む場合r」の情報を追跡することで、オープンスポットへのジャンプのスキャンを大幅に節約できます時間。

  • 到達可能性を追跡し、ビットマスクを使用して(反転した動的アルゴリズムで)ログファクター削り、ターゲットの残りに到達したらバックトラックすることができます。

  • 動的プログラミングアルゴリズムは、並列実行に非常に適しています。各バッファスロットのプロセッサを使用すると、到達できます。あるいは、幅を使用し、反復集約の代わりに集約を分割して征服することにより、回路の深さのコストをまで下げることができます。O(n)O(n2)O(log2n)

  • (メタ)あなたが与えられた問題は、連続した金額に関するものだと強く思います。実際の問題にリンクしている場合は、簡単に確認できます。それ以外の場合、「アルゴリズムの紹介」と呼ばれるコースで割り当てられたこの問題の難しさに非常に驚かされます。しかし、あなたはクラスでそれを簡単にするトリックをカバーしたかもしれません。


ポイント1。問題の仕様には書かれていないので、それを想定することはできません。また、問題は、配列を変更したり、新しい配列を作成したりできないということではありません。あなたがする必要がある唯一のことは、時間の複雑さでで割り切れる最大の合計を与える合計を見つけることです(通常は時間の複雑さだけと仮定されます)。nO(n)
-nbro

2
@EvilJS剰余0の最大合計を持つサブセットは、フルセットの合計と一致する剰余の最小合計を持つサブセットを削除した後、フルセットに等しくなります。一致する最小の合計を検索することは、一致する最大の合計を検索するよりも、続行する代わりに(要素を昇順で処理する場合)解決策を見つけるとすぐに終了できるため便利です。r1r2
クレイグギドニー

-1

私の提案するアルゴリズムは次のとおりです。

nの倍数である被加数のみを追加する場合、合計はnで割り切れます。

開始する前に、キーとしてintを、値としてインデックスのリストを使用してハッシュマップを作成します。また、インデックスを含む結果リストを作成します。

次に、配列をループし、mod nがゼロであるすべてのインデックスを結果リストに追加します。他のすべてのインデックスについては、次を実行します。

このインデックスの値mod nをnから減算します。この結果は、必要な値を持つ要素のインデックスを保存するハッシュマップのキーです。次に、このインデックスをハッシュマップのリストに追加して先に進みます。

配列のループ処理が完了したら、出力を計算します。これを行うには、インデックスが指す値に従ってハッシュマップ内の各リストをソートします。ここで、合計nまでのハッシュマップのすべてのペアを検討します。したがって、n = 7の場合、3と4のハッシュマップを検索します。両方のエントリを取得した場合、2つの最大値を取得してリストから削除し、結果リストに追加します。

最後の推奨事項:アルゴリズムをまだテストしていませんでした。ブルートフォースアルゴリズムを使用して、それに対するテストケースを作成します。


2
貪欲、線形、動作していません。nで割り切れる要素とnで割り切れるペアのみを考慮しますが、トリプルなどはどうでしょうか?些細な場合の最大サブセット合計を保証するものではありません。[2、1、8] - >最大の合計は9ですが、あなたのアルゴリズムのリターン3
悪の

@EvilJS subアルゴリズムで何が起こったのですか?n2
デルタターミネーター

この間違いを指摘してくれてありがとう。改善に関する私の考えは、値の増加順に並べられたリストのスタックのハッシュマップを作成し、配列のパスが完了した後にのみ蓄積を開始することです。
トビアスヴルフル

配列の配列を意味します。これはソートされ、「ハッシュマップ」は%nですか?あなたはまだそれらをソートする必要があり、あなたがそれらをソートしている場合、最小/最大値を取ることはOKですが、実際にはサブセットを選択するのは避けられない部分があり、最悪の場合には利益がありません。とにかくいくつかの改善点があれば、投稿を編集できますか?
邪悪な

ええ、スタックについては非常に簡単なアイデアでした。実際、ソートするハッシュマップのリストのみが必要です。最初の回答を編集するのが礼儀正しいかどうかはわかりませんでした。結局、私は最初の試みで間違いを犯しました。
トビアスヴルフル16年

-2

/programming/4487438/maximum-sum-of-non-consecutive-elements?rq=1)からこのDPメソッドを使用します

配列A [0..n]が与えられた場合、インデックス0..iの要素を使用してM(i)を最適なソリューションにします。次に、M(-1)= 0(繰り返しで使用)、M(0)= A [0]、およびM(i)= max(M(i-1)、M(i-2)+ A [i ])i = 1、...、nの場合。M(n)は私たちが望む解です。これはO(n)です。別の配列を使用して、各サブ問題に対してどの選択が行われたかを保存し、選択された実際の要素を復元できます。

Nで割り切れる場合にのみ保存されるように、再帰をM(i)= max(M(i-1)、M(i-2)+ A [i])に変更します。


2
これは機能しません。その理由を説明します。(ヒント:定数1配列で実行してみてください。)また、この問題では、連続した要素を許可します。
ユヴァルフィルマス16年

1
これは非常に優れたソリューションであり、まったく異なる(そしてはるかに簡単な)問題に対するものです。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.