• home
  • about
  • 全ての投稿
  • ソフトウェア・ハードウェアの設定のまとめ
  • 分析関連のまとめ
  • ヘルスケア関連のまとめ
  • 生涯学習関連のまとめ

meet in the middle

date: 2021-04-24 excerpt: 半分全列挙について

tag: algorithmdynamic programmingbrute forcemeet in the middle


半分全列挙(meet in the middle)について

  • 組み合わせの表現が爆発するとき、その表現を半分に分割して探索する
  • Xの値を得たい時、プロセスAでwを作り、プロセスBでX-wを作るとこの結果の組み合わせが特定のパターンの探索になっている

具体的な例

N個の重さw_iの品物を組合わせてXの重さを作る時、何通りあるか

もとの問題

入力

N X
w_1
w_2
.
.
.
w_n
5 5
1
1
2
3
4

コード

from collections import defaultdict

N, X = list(map(int, input().split()))

A = []
B = []

for i in range(N):
    w = int(input())
    if i % 2 == 0:
        A.append(w)
    else:
        B.append(w)


def has_bit(n, i):
    return (n & 1 << i) > 0


dic = defaultdict(int)

for n in range(1 << len(B)):
    w = 0
    for i in range(N):
        if has_bit(n, i):
            w += B[i]
    dic[w] += 1


ans = 0
for n in range(1 << len(A)):
    w = 0
    for i in range(N):
        if has_bit(n, i):
            w += A[i]
    ans += dic[X - w]

print(ans)


algorithmdynamic programmingbrute forcemeet in the middle Share Tweet