Module: 真ん中で会う


Problem

1 /5


モジュロ最大サブシーケンス

Theory Click to read/hide

中間者会
中間者間 - 最適化する方法解決策は、元の問題を 2 つに分割し、それぞれを独立して解決し、その後、半分の解決策を組み合わせて元の問題の解決策を取得することで構成されます。

したがって、2 つの条件が満たされる場合は、meet-in-the-middle を使用するのが合理的です。
1) 問題の半分を解くのに必要な時間は、問題全体を解くのにかかる時間よりも漸近的に短くなります。
2) 半分の問題を解くことで、元の問題全体の解を得ることができ、同時に、問題全体を解くよりも漸近的に速く解決できます。
 
ABCD という 4 つの整数配列があるとします。これらの数値の合計がゼロになるように、各配列から数値を 1 つだけ選択する必要があります。単純な解決策、つまり、考えられるすべてのオプションを単純に列挙することもできます。これは O(n4) で機能します。

ただし、meet-in-the-middle を使用することはできます。
a + b + c + d = 0(a + b) = -(c + d) と同等であることに注意してください。
タスクを 2 つの半分に分割しましょう。つまり、前半では配列 AB のみを使用し、後半では C のみを使用します。 > と D
前半で可能なすべての (a + b) オプションを反復処理し、すべての値をハッシュ テーブル (unowned_mapHashMap など)。これは O(n2) で機能します。
ここで、後半ですべての可能なオプション (c + d) を反復処理します。特定のオプションを検討するとき、反対の符号の現在の合計に関連付けられた値がハッシュ テーブルに存在するかどうかを確認します (その後、合計するとゼロになる 2 つの逆数が見つかりました)。この部分は O(n2) でも機能します。
ここには個別の「回答のマージ」フェーズはありません。 1 つ目では、各半分を解決する過程でこれを実行しました。ほとんどのタスクでも同様の状況が発生します
。 最終的には、meet-in-the-middle を使用した O(n2) で解決策を導き出しました。

meet-in-the-middle は、指数関数的な解を最適化するときに最もよく使用され、実行時間に大きな影響を与えることに注意してください。

Problem

n 個の正の整数と数値 m で構成される配列 A が与えられた場合、位置 のシーケンスを選択しますB 1, B2, ..., Bk > (1 <= B1 < B2 < ... < Bk <= n)   ; \((\sum_{i=1}^{k} A_{B_i}) mod \; m\)  が最大 (つまりであるため、 サブシーケンスの要素の合計を数 m で割った余りが可能な最大値になります) 選択したシーケンスは空にすることができます。
\((\sum_{i=1}^{k} A_{B_i}) mod \; m\) の最大値を計算します。

入力
最初の行には、2 つの整数 nm (1 <= n <= 35, 1 <= m <= 109). 2 行目には n 個の整数 A1, A2 が含まれます>, ..., An (1 <= Ai <= 109 )< br />
インプリント
数値を 1 つ出力 - 最大値 \((\sum_{i=1}^{k} A_{B_i}) mod \; m\)

 
<頭> <本体>  
説明
最初の例では、B = {1, 2} を選択できます。 (A1 + A2) mod m = (5 + 2) % 4 = 3.
2 番目の例では、B = {3} を選択できます。
# 入力 出力
1 4 4
5 2 4 1
3
2 3 20
199 41 299
19