この記事で使うアルゴリズム
全探索
はじめに
カテゴリー競プロ初中級者100問では、Qiita
にて@e869120
さんがレッドコーダーが教える、競プロ・AtCoder上達のガイドライン【中級編:目指せ水色コーダー!】としてまとめられている100問をPython
で解いています。
全問題の一覧はこちらです
問題
https://atcoder.jp/contests/abc002/tasks/abc002_4
この問題は全探索を用いて解くことができます。
方針
- 議員の集合を考えます。その集合内で考どの二人を選んでも二人が知り合いである場合、その集合は派閥にすることができます。
- 議員の集合として考えられる組み合わせは
2^N-1
通りとなります。- 理由は、集合に所属する議員を1、そうでない議員を0として表現するとわかりやすいでしょう。
ポイント
議員の集合として考えられる組み合わせ
を列挙する方法として、ループを回して二進数に変換する方法が考えられます。
(例)N=5の場合
1 | 1 -> 00001 |
しかし、Pythonの場合は標準ライブラリitertools.combinations
を使うと楽に実装できます。
以下のように、組み合わせを簡単に列挙することができます。
1 | for comb in combinations(range(3),2): |
1 | (0, 1) |
コード
それでは実装にうつりましょう。
知り合いであるかどうかをlink
を使って表します。
1 | from itertools import combinations |
続いて、議員の集合として考えられる組み合わせ
を列挙します。
最大の派閥に属する議員数
を求めたいので、議員数が多くなるような集合から先に考えます。
1 | ans = 1 |
議員の集合
に対して考えられるペアを列挙し、知り合いかどうかをチェックします。
一つでも知り合いでない組があれば、その集合は派閥にはなり得ません。
ここで、またcombinations
が有効です。
1 | for c in combinations(comb, 2): # 議員の集合に対して考えられるペアを列挙 |
最後にコード全体を載せておきます。
コード(全体)
1 | from itertools import combinations |
記事情報
- 投稿日:2020年4月14日
- 最終更新日:2020年5月8日