JOI難易度6 おせんべい
問題原文
問題要旨
× のグリッドがあり、各セルは 1
か 0
かである。
ある行を好きなだけ選び、その行の1と0を反転 → ある列を好きなだけ選び、その列の1と0を反転 という操作を1回行う。
操作後のグリッド上の 0と書かれたセルの数を最大化せよ。
- 実行時間制限 10sec
解法
行についての制約が小さいので、行の選び方を全探索する。
すると各列について、
- 1の数が多い → 反転するほうがよい
- 0の数が多い → 反転しないほうがよい
という状態になる。あとは0の数が最大になるように、各列について計算を行えばよい。
- 行の選び方を全探索 →
- 各列について、行の操作後にいくつ0になっているかを計算 →
なので、計算量は になる。
実行時間制限が相当に緩いので余裕で間に合う。
実装
itertools.product
を使うと楽。
from itertools import product R, C = map(int, input().split()) G = [list(map(int, input().split())) for _ in range(R)] ans = 0 for pattern in product([0, 1], repeat=R): tmp_ans = 0 reverse_tips = [0] * C for r in range(R): for c in range(C): if pattern[r] == G[r][c]: reverse_tips[c] += 1 for rc in reverse_tips: tmp_ans += max(rc, R - rc) ans = max(ans, tmp_ans) print(ans)
感想
特徴的な制約に注目、というのは基本ですね。