差分

このページの2つのバージョン間の差分を表示します。

この比較画面へのリンク

両方とも前のリビジョン前のリビジョン
次のリビジョン
前のリビジョン
最新のリビジョン両方とも次のリビジョン
programming_algorithm:contest_history:atcoder:2019:0504_agc033 [2019/05/09] – [解法] ikatakosprogramming_algorithm:contest_history:atcoder:2019:0504_agc033 [2019/05/10] – [解法] ikatakos
行 38: 行 38:
     * $185^4 = 1,171,350,625$ であり、この時点で整数1個1byteとしても、メモリ制限を超えてしまう     * $185^4 = 1,171,350,625$ であり、この時点で整数1個1byteとしても、メモリ制限を超えてしまう
   * 計算量   * 計算量
-    * ある長方形の複雑さを求めるには、全ての分割を試して最を求める必要があり、計算量が $O(H^2W^2(H+W))$ くらいかかる(もっと効率的な方法があるのかも知れないが)+    * ある長方形の複雑さを求めるには、全ての分割を試して最小値を求める必要があり、1つの長方形につき $O(H+W)$、全体で $O(H^2W^2(H+W))$ くらいかかる(もっと効率的な方法があるのかも知れないが)
  
 ===解説の方法=== ===解説の方法===
行 57: 行 57:
 $(a,b,c)$ によっては複雑度 $k$ では長方形が作れないかも知れないので、その場合はそれと分かる値、たとえば''-1''で埋めておく。 $(a,b,c)$ によっては複雑度 $k$ では長方形が作れないかも知れないので、その場合はそれと分かる値、たとえば''-1''で埋めておく。
  
-DPは2段階で更新する。まず、DP1を使ってDP1を、DP2を使ってDP2を暫定更新する。次に、双方情報を合わせてDP1、DP2修正更新する。+まず、$k=0$ 埋める。
  
-まず第1段階。a,b,cが決めれたとき、「縦に分割するとし」複雑さkの長方形を最大とることを考える左右とも複雑さ $k-1$ になる長方形に分割するがよい。+$DP1[0][a][b][a]$ は、$(a,b)$ か数えて $a$ 行で同色が続く右限。これは各 $a$ に対して $b$ 大き方から埋められる
  
-    複雑さk-1     複雑さk-1+$DP1[0][a][b][c]$ は、まず $(a,b)~(c,b)$ が全て同色でなければ ''-1''。同色なら $DP1[0][a][b][c]~DP1[0][c][b][c]$ の最小値で、各 $a,b$ に対して $c$ の小さい方から埋められる。 
 + 
 +続いてDPの遷移を考える。2段階で更新する。まず、DP1を使ってDP1を、DP2を使ってDP2を暫定更新する。次に、双方の情報を合わせてDP1、DP2を修正更新する。 
 + 
 +まず第1段階。a,b,cが決められたとき、「縦に分割すると決めて」複雑さkの長方形を最大限とることを考える。左右とも複雑さ $k-1$ になる出来るだけ広い長方形に分割するのがよい。 
 + 
 +    複雑さk-1 r   複雑さk-1
   (a,b)------>|(a,r+1)------->|   (a,b)------>|(a,r+1)------->|
   |                         |   |                         |
行 75: 行 81:
 よって、DP1[k-1][a][b][c] でまず左の長方形の右端を求めて(rとする)、次にDP1[k-1][a][r+1][c] で右の長方形の右端を求めると、それがDP1[k][a][b][c]の暫定値となる。 よって、DP1[k-1][a][b][c] でまず左の長方形の右端を求めて(rとする)、次にDP1[k-1][a][r+1][c] で右の長方形の右端を求めると、それがDP1[k][a][b][c]の暫定値となる。
  
-DP2も、縦方向に同様にすれば求められる。+DP2も、同様にすれば、横に分割すると決めた場合の暫定値を求められる。
  
 次に、先ほどの更新は縦に分割するという仮定をおいたが、実際は横に分割した方が複雑さが抑えられ、より右まで複雑度 $k$ のまま範囲を伸ばせるかも知れない。 次に、先ほどの更新は縦に分割するという仮定をおいたが、実際は横に分割した方が複雑さが抑えられ、より右まで複雑度 $k$ のまま範囲を伸ばせるかも知れない。
-横方向の分割での最適な下限はDP2にあるので、それを使ってDP1を更新する。+横方向の分割での最適な下限は $DP2[k]$ にあるので、それを使ってDP1を更新する。
  
 a,bを固定して、dを大きい方から見ていく。 a,bを固定して、dを大きい方から見ていく。
行 85: 行 91:
   |   |
  
-もしある $d=d_2$ の時、DP2によって、複雑度 $k$ の長方形の下限が $c_2$ であるとわかったとする。+もしある $d=d_2$ の時、$DP2によって、複雑度 $k$ の長方形の下限が $c_2$ であるとわかったとする。
  
   (a,b)               (a,d2)   (a,b)               (a,d2)
行 92: 行 98:
                      (c2,d2)v                      (c2,d2)v
  
-$DP1[a~c_2][b][c_2]$ と $d_2$ を各個比較し、もし $d_2$ の方がより右なのであれば、$d_2$ に更新する。+$DP1[k][a][b][a]DP1[k][a][b][c_2]$ と $d_2$ を各個比較し、もし $d_2$ の方がより右なのであれば、$d_2$ に更新する。
  
   (a,b)            |  (a,d2)   (a,b)            |  (a,d2)
行 128: 行 134:
 ===説明のための特殊化=== ===説明のための特殊化===
  
-'R'と'B'を全て逆転して考えても答えは変わらないので、$S$ が'B'から始まる場合は逆転させて、'R' から始まるとして説明する。+'R'と'B'を全て逆転して考えても答えは変わらないので、$S$ が'B'から始まる場合は逆転させて、全て 'R' から始まるとして説明する。
  
 ===制約=== ===制約===
行 143: 行 149:
 <WRAP center round box> <WRAP center round box>
 ここで、$S$ が全て'R'だった場合、1.の条件さえ満たせばよい。 ここで、$S$ が全て'R'だった場合、1.の条件さえ満たせばよい。
-この場合の数え上げは、フィボナッチ数列のようにしてできる。+この場合の数え上げは、フィボナッチ数列のようにしてできる。直線上で考え、先頭と末尾がともに青にならないように注意する。 
 + 
 +                    長さ      2    3    4    5    6 
 +  赤から始まり、末尾が赤   1 → 1 → 2 → 3 → 5 → 8 
 +                             ×   ×   ×   ×   ×    \ 
 +  赤から始まり、末尾が青      1    1    2    3    5  ー この3つの合計が答え 
 +                                                       / 
 +  青から始まり、末尾が赤   0 → 1 → 1 → 2 → 3 → 5 
 +                             ×   ×   ×   ×   ×   
 +  青から始まり、末尾が青      0    1    1    2    3
 </WRAP> </WRAP>
  
行 149: 行 164:
  
 $S$ に'B'が含まれる場合、'R'から'B'に切り替わるタイミングで、円周上の移動でも赤と青の境界に存在できないといけない。両方が赤の点で'B'への切り替わりを迎えてしまうとアウト。 $S$ に'B'が含まれる場合、'R'から'B'に切り替わるタイミングで、円周上の移動でも赤と青の境界に存在できないといけない。両方が赤の点で'B'への切り替わりを迎えてしまうとアウト。
-('B'→'R'も同じ事は言えるが、青は連続しないので、必ず両端に赤がある) 
  
 すると、連続する赤の個数にも制約が生じる。結論から言うと、奇数個でなければいけない。 すると、連続する赤の個数にも制約が生じる。結論から言うと、奇数個でなければいけない。
行 169: 行 183:
   * 奇数個だった場合、奇数番号の点から出発するケース   * 奇数個だった場合、奇数番号の点から出発するケース
  
-では、移動後に存在できるのが偶数番号の点であり、どうやっても1や3といった赤と青の境界に存在できない。+では、移動後に存在できるのが偶数番号の点となり、どうやっても奇数番号の赤と青の境界に存在できない。
  
 $K$ が奇数個なら左右端で偶奇を選べるので、どの点から出発しても青に移行できる。 $K$ が奇数個なら左右端で偶奇を選べるので、どの点から出発しても青に移行できる。
行 196: 行 210:
 ^連続できる赤|1|3|3|5|5|7|7|...|k/2*2+1| ^連続できる赤|1|3|3|5|5|7|7|...|k/2*2+1|
  
-また、2番目の条件「...→青→奇数個の赤→青→...」は、先ほどの偶奇を考えると、赤を端から端まで貫通する必要がある。+また、2番目の条件「...→青→奇数個の赤→青→...」の移動は、先ほどの偶奇を考えると、赤を端から端まで貫通する必要がある。
  
 'R'が偶数個なら入った端点と出る端点が同じなので引き返せばいいのだが、奇数個なら入端点と出端点は異なり、貫通が必要になる。 'R'が偶数個なら入った端点と出る端点が同じなので引き返せばいいのだが、奇数個なら入端点と出端点は異なり、貫通が必要になる。
行 204: 行 218:
   →→,             →→→→→→→   →→,             →→→→→→→
   ←←'   ←←'
-    +
 じゃあ、そういう、赤が長く連続する箇所を避けるように選択して移動できないかというと、無理。 じゃあ、そういう、赤が長く連続する箇所を避けるように選択して移動できないかというと、無理。
  
-実はあんまり移動の自由度がなくて、'R','B'が連続する個数と入端点によって、出られる端点は一意に決まるので、+実はあんまり移動の自由度がなくて、'R','B'が連続する個数の偶奇と入端点によって、出られる端点は一意に決まるので、
 出発点を決定した時点で、「$i$ 回目の移動後には、この連続する赤/青の区間のどこかに存在する」というのが決まってしまう。 出発点を決定した時点で、「$i$ 回目の移動後には、この連続する赤/青の区間のどこかに存在する」というのが決まってしまう。
  
行 221: 行 235:
                    ------     5ではこの上のどこかにいて、右端から出る                    ------     5ではこの上のどこかにいて、右端から出る
  
-赤が連続する区間は、どこかからの出発点で必ず通られる。+全ての赤が連続する区間は、どこかからの出発点で必ず通られる。
  
 よって、円周上で赤が連続する箇所は全て、$S$ 上で'B'に挟まれた最も短い奇数個の'R'の個数を超えてはならない。 よって、円周上で赤が連続する箇所は全て、$S$ 上で'B'に挟まれた最も短い奇数個の'R'の個数を超えてはならない。
行 273: 行 287:
 $dp[N]$ まで埋めたら、回転のバリエーションを考える。本問題では、回転して同じになるものは区別する。 $dp[N]$ まで埋めたら、回転のバリエーションを考える。本問題では、回転して同じになるものは区別する。
  
-単純に直線を円周に当てはめる位置を $N$ 通りずらすので、$dp[N]$ を $N$ 倍すればよいなんてことにはならず、+単純に直線を円周に当てはめる位置を $N$ 通りずらすので、$dp[N]$ を $N$ 倍すればよい...なんてことにはならず、
 例えば「赤赤赤青赤赤赤青」などは半回転した結果が全く同じになるので、重複してしまう。 例えば「赤赤赤青赤赤赤青」などは半回転した結果が全く同じになるので、重複してしまう。
  
programming_algorithm/contest_history/atcoder/2019/0504_agc033.txt · 最終更新: 2019/05/10 by ikatakos
CC Attribution 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0