AtCoder Beginner Contest 347 F,G問題メモ

F - Non-overlapping Squares

問題

  • $N \times N$ グリッドの各マスに、非負整数 $A_{i,j}$ が書かれている
  • グリッドから $M \times M$ の正方形のマス目を重ならずに3つ選ぶ
  • 選んだマス目に書かれている $A_{i,j}$ の総和として考えられる最大値を求めよ
  • $2 \le N \le 1000$
  • $1 \le M \le N/2$

解法

正方形を選ぶ個数が3つというのが重要で、必ずグリッド全体を、正方形を切らずに「1:2」で分けられる直線が存在する。

□□□□□□□
□□□●●□□
□☆☆●●□□
□☆☆□□□□__↙この線で分割できる
□□▲▲□□□
□□▲▲□□□
□□□□□□□

(4つ以上だと無理な配置が存在する)

□□□□□□□
□□□●●□□  どの直線で切ってもどれかの正方形が分割される
□☆☆●●□□
□☆☆□◎◎□
□□▲▲◎◎□
□□▲▲□□□
□□□□□□□

2個の方はさらに1個ずつに分けられるので、グリッドを「それぞれ1個ずつ正方形を内包する」という3つの領域に分けられる。

縦または横に3つに切る型
①❷③  ①①①
①❷③  ❷❷❷      ※❷だけ黒いのは、単に視認性のため
①❷③  ③③③

T字型
①①①  ①❷❷  ①①❷  ①①③
❷❷③  ①③③  ①①❷  ❷❷③
❷❷③  ①③③  ③③③  ❷❷③

この分け方・分ける位置を全探索する。分ける位置を決めたときの答えを効率的に求められるよう、前計算する。

その後、❷に含まれる正方形の位置を全探索する。

1つ決め打つと、どの分け方のパターンをとっても、その正方形と被らない最大の①、③の領域が決まり、 その領域内に内包される正方形の最大スコアは、(b) を参照するとすぐに調べることができる。

(a)、(b)の前計算と、❷の位置の全探索、いずれも $O(N^2)$ でできる。

Python3

G - Grid Coloring 2

問題

  • $N \times N$ のグリッドが与えられる
  • マス $(i,j)$ には整数 $A_{i,j}$ が書かれている。$A_{i,j}$ は $0~5$ の整数である
  • 以下の操作を好きなだけ行える
    • $0$ が書かれたマスの数字を、$1~5$ のいずれかに書き換える
  • グリッドのコストを、「上下または左右に隣接する全ての2マス間に書かれた数の差の2乗の総和」とする
  • コストが最小となる、操作後の盤面の一例を示せ
  • $1 \le N \le 20$

解法

グラフを上手く作って、最小カット問題に落とし込む。

コストが2乗であり、「離れれば離れるほどコストの増え方が増加する」ような形をしているため、上手くコストを設定できる。1)
仮に、「1離れてればコスト1、2離れてたら5、3離れてたら8」のように、 コストの増分が 1→5で4、5→8で3 と減っている箇所があるような形だったらダメ。

最小カットで解けるようにグラフを作り、コストを設定する。

  • 最小カットは、頂点をグループSとTに分ける分け方で、S→T に張られた辺コストの合計を最小化する問題である
    • ただし、s は必ずグループ S、t はグループ T とする

1つのマスにつき、以下のような4頂点を割り当て、s-t で結んだものを考える。
頂点“(2以上)“は、S に属するとき、そのマスの数字が2以上であることを示す。T に属すると2未満となる。

マスa   ,---> (2以上) ---> (3以上) ---> (4以上) ---> (5以上) ---,
マスb  s ---> (2以上) ---> (3以上) ---> (4以上) ---> (5以上) ----> t
マスc   `---> (2以上) ---> (3以上) ---> (4以上) ---> (5以上) ---'
  :

このようなグラフ上で辺のコストを考える。

1つのマスの中の制約に関するコスト

矛盾を防ぐ

あるマスの数字が3以上かつ2未満であることは当然だがあり得ない。
つまり、(3以上)がS、(2以上)がTであることは許されない。
そのようなグループ分けが発生しないよう、戻るINF辺を張る。

s      (2以上) <-INF- (3以上) <-INF- (4以上) <-INF (5以上)      t
初期値

既に0以外の値が埋められたマスは、そのマス以外の数字を選べないよう、INF辺を設定する。

はじめから 3 が埋められたマス

s -INF-> (2以上) -INF-> (3以上)      (4以上) -INF-> (5以上) -INF-> t

0であるマスは、どの数字を選ぼうとも「そのマス単体だけの」コストは発生しないので、辺コストは全て0である。
(したがって、実際には辺を張る必要は無い)

s --0--> (2以上) --0--> (3以上) --0--> (4以上) --0--> (5以上) --0--> t

2つのマスの関係性に関するコスト

まず、マスaが3、マスbが4の場合を考えてみる。グリッドのコストへの寄与は1である。

                 S            S            T            T
マスa   ,---> (2以上) ---> (3以上) ---> (4以上) ---> (5以上) ---,
       s                                  ↑1                    -> t
マスb   `---> (2以上) ---> (3以上) ---> (4以上) ---> (5以上) ---'
                 S            S            S            T

(4以上)の間に1の辺を張れば、実現できる。
他の(2以上)、(3以上)、(5以上) の間にも同様のことが言えるので、それぞれにコスト1の辺が張られる。

マスaが2、マスbが4の場合を考えてみる。グリッドのコストへの寄与は4である。

                 S            T            T            T
マスa   ,---> (2以上) ---> (3以上) ---> (4以上) ---> (5以上) ---,
       s                     ↑1   ↖2    ↑1                    -> t
マスb   `---> (2以上) ---> (3以上) ---> (4以上) ---> (5以上) ---'
                 S            S            S            T

このとき、既に(3以上)と(4以上)の間にそれぞれコスト1が張られているので、追加で必要なコスト2の辺を、ナナメに張ればよい。

さらにマスaが1、マスbが4の場合を考えてみる。グリッドのコストへの寄与は9である。

                 T            T            T            T
マスa   ,---> (2以上) ---> (3以上) ---> (4以上) ---> (5以上) ---,
       s        ↑1   ↖2    ↑1   ↖2    ↑1                    -> t
マスb   `---> (2以上) ---> (3以上) ---> (4以上) ---> (5以上) ---'
                 S            S            S            T

既に1,2,1,2,1のコストの辺が張られているので、追加で必要なのは2である。bの(4以上)→aの(2以上) に、コスト2の辺を張る。

このように、異なる頂点間で

  • 同じ意味合いの頂点間にはコスト1
  • 違う意味合いの頂点間には戻る方向にコスト2

の辺を張れば、「差の2乗」を表現できる。

この過程で、どの辺コストも負にならないために必要なのが、 最初の「離れれば離れるほどコストの増え方が増加する」性質となる。

復元

コストを求めるだけなら簡単だが、今回はその盤面を構築しなければならない。

最小カットを流すと、「どの辺がカットされたか」は、再度始点から調べることで列挙できる。

例えば、マスaの(4以上) → マスbの(3以上) の辺がカットの1つにあった場合、

  • マスaの(4以上)はSグループなので、マスaは4以上確定
  • マスbの(3以上)はTグループなので、マスbは2以下確定

このように、最大・最小の両側から範囲が限定される。
マスによっては、最大方向・最小方向の片方からしか限定されないものもあるが、その場合は限定された方を採用する。

これで調べていけるのだが、あくまでカット辺は「コストが発生する」辺なので、

3 3 3 3
3 0 0 3
3 3 3 3

の'0'のように、コストが最大4方向のいずれでも発生させないことができるマスは、カット辺に関与せず、範囲が限定されないままとなる。

ただ、このような頂点は四方を同じ数字で囲まれているはずなので、後からDFSなり何なりすれば補間出来る。

Python3

1)
Monge性という
programming_algorithm/contest_history/atcoder/2024/0330_abc347.txt · 最終更新: 2024/04/03 by ikatakos
CC Attribution 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0