差分

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

この比較画面へのリンク

両方とも前のリビジョン前のリビジョン
次のリビジョン
前のリビジョン
次のリビジョン両方とも次のリビジョン
programming_algorithm:contest_history:atcoder:2019:0323_agc032 [2019/04/19] ikatakosprogramming_algorithm:contest_history:atcoder:2019:0323_agc032 [2019/04/21] ikatakos
行 363: 行 363:
  
 <sxh python> <sxh python>
-from collections import defaultdict +from bisect import bisect
-from operator import itemgetter+
  
 n, a, b = map(int, input().split()) n, a, b = map(int, input().split())
-ppp = list(map(int, input().split())) +ppp = map(int, input().split()) 
-qqq = list(map(itemgetter(0)sorted(enumerate(ppp, start=1), key=itemgetter(1))))+qqq = [0] * n 
 +for ip in enumerate(ppp, start=1)
 +    qqq[p - 1] i
  
-dp = {00}+dp = [(00)]
 for i in qqq: for i in qqq:
-    ndp defaultdict(lambda: 10 ** 18+    bisect(dp, (i,)
-    for j, cost in dp.items()+    ndp = [(j, cost + b) for j, cost in dp[:s]] 
-        if j < i: +    stay_cost = dp[s - 1][1] 
-            ndp[imin(ndp[i], cost) +    ndp.append((i, stay_cost)) 
-            ndp[j] = min(ndp[j], cost + b+    remain iter(dp[s:]
-        else: +    for j, cost in remain: 
-            ndp[j] = min(ndp[j], cost + a)+        if stay_cost > cost + a: 
 +            ndp.append((j, cost + a)
 +            break 
 +    ndp.extend((j, cost + a) for j, cost in remain)
     dp = ndp     dp = ndp
- +print(dp[-1][1])
-print(min(dp.values()))+
 </sxh> </sxh>
  
行 392: 行 395:
  
   * 正整数 $M$ がある   * 正整数 $M$ がある
-  * $2N$ 個の整数 $a_1,a_2,...,a_{2N}$ があり、全て $0 \le a_i \lt M$ +  * $2N$ 個の、$0 \le a_i \lt M$ の整数 $a_1,a_2,...,a_{2N}$ があ 
-  * これを2つずつ組み合わせて $N$ 個のペアを作る +    * これを2つずつ組み合わせて $N$ 個のペアを作る 
-  * ペアの数字をそれぞれ $x,y$ として、$(x+y) \mod{M}$ の、$N$ 個のペアの中での最大値を$X$とする +  * ペアの「醜さ」を、ペアの数字をそれぞれ $x,y$ として、$(x+y) \mod{M}$ とする 
-  * $X$ が最小となるようにペアを作ったときの $X$ の値を求めよ+  * $N$ 個のペアの中での醜さの最大値を $Z$ とする 
 +  * $Z$ が最小となるようにペアを作ったときの値を求めよ
   * $1 \le N \le 10^5$   * $1 \le N \le 10^5$
   * $1 \le M \le 10^9$   * $1 \le M \le 10^9$
行 401: 行 405:
 ==== 解法 ==== ==== 解法 ====
  
-解説pdfを読んだら理解と実装は比較的簡単だが……発想飛躍…… +解説pdfを読んだら理解と実装は比較的簡単だが、考察時点で結構地道なパターン分け必要。
- +
-===いろいろ試す===+
  
 最大値をなるべく低く抑えるということは、ペアの合計を均等にした方が良さそうなので、大きいのと小さいのを組み合わせる方向性が思いつく。 最大値をなるべく低く抑えるということは、ペアの合計を均等にした方が良さそうなので、大きいのと小さいのを組み合わせる方向性が思いつく。
  
-  M=10 +  ,---------,  M=10
-  ,---------,+
   |   ,-,   |   |   ,-,   |
   0 2 3 4 5 9   0 2 3 4 5 9
     `-----'     `-----'
  
-仮に、$\mod{M}$ の条件がないのであれば、つまり単にペアの和の最大値を低く抑えるのであれば、この組合せ方が正解となる。(解説pdfの、青色同士の組み替え参照)+仮に、$\mod{M}$ の条件がないのであれば、つまり単にペアの和の最大値を低く抑えるのであれば、この組合せ方が正解となる。
  
-でもの問題だと $X=9になり$M=10$ なまり有効そうではない。$\mod{M}$ を有効活用したい+<WRAP round box> 
 +れを確認する。$a \le b \le c \le dとしてペア組み方は3通り
  
-  ,-----, +  A              B              C 
-  | ,-, | ,-, +  ,--,        |  ,-----,      ,--------, 
-  0 2 3 4 5 9+  a  b  c  d    b  c  d  |  a  b  c  d 
 +        `--'  |     `-----'  |     `--' 
 + 
 +ある2通りのペアの組み方 $A,B$ があって、醜さの最大値の比較で $Z_A \le Z_B$ と言うためには、 
 +「$A$ の全てのペアについて、それぞれ、より醜さが大きいペアが $B$ に存在する」ということが言えればよい。 
 + 
 +すると、$C$ のペアは、 
 + 
 +  (C) a + d  <=  (A) c + d    (C) b + c  <=   (A) c + d 
 +  (C) a + d  <=  (B) b + d    (C) b + c  <=   (B) b + d 
 + 
 +となり、$A,B$ より醜さの最大値は小さくなることが分かる。 
 + 
 +もっとペアの数が増えても、上記のことを1つ1つ順に適用していくことで、最終的に「小さい方と大きい方から順に組み合わせていく」方針が最適となることが分かる。 
 + 
 +</WRAP>
  
-1つ大きい数字同士でペアを作ってから、残っで大小組み合わせる$X=5$ となり、サンプル出力例と一致する。 +だ、先ほど例だと $Z=9になる。$M=10$ なので、答えとなり得る値の中で最大であり、まま適用するのはあまり有効そうではな。$\mod{M}を有効活用したい。
-適切なペアこん感じになるようだ +
-ただ $Nが少なすぎて、どういう風に一般化すればいいか、まだ決めづらい。+
  
 ところで、各数字は $0 \le a_i \lt M$ なので、2つ足しても $2M$ を超えることはない。「和が $M$ を超えるペア」のスコアは必ず「2数の和$-M$」である。つまり、「和が $M$ を超えるペア」同士の間では、2数の和がそのまま大小比較に使える。 ところで、各数字は $0 \le a_i \lt M$ なので、2つ足しても $2M$ を超えることはない。「和が $M$ を超えるペア」のスコアは必ず「2数の和$-M$」である。つまり、「和が $M$ を超えるペア」同士の間では、2数の和がそのまま大小比較に使える。
  
-なので「和が $M$ 未満のペアに使われる数字」「$M$ 以上のペアに使われる数字」に分類した際、の中での適切なペアの作り方は、やはり大きいと小さいのを組み合わせる方針でる。+なので「和が $M$ 未満のペアに使われる数字」「$M$ 以上のペアに使われる数字」に分類した際、各分類の中での適切なペアの作り方は、やはり大きいと小さい方から順に組み合わせる方針が適用る。
  
-  ※a~hはソート済み+  ※a~hは昇順にソート済み
           ,--------------,           ,--------------,
           |     ,--,     |           |     ,--,     |
行 437: 行 452:
              `-----------------'              `-----------------'
  
-ここから、分類を組み替えることで、より $X$ を小さく出来ないか考える。+ここから、分類を組み替えることで、より $Z$ を小さく出来ないか考える。
  
 こんなペア(左)があった時、こうする(右)と、 こんなペア(左)があった時、こうする(右)と、
行 448: 行 463:
           b + d - M           c + d - M           b + d - M           c + d - M
  
-  * $a+c$ で $M$ 未満なのだから、$a+b$ は $M$ 未満 +  * (左) $a+c$ で $M$ 未満 => (右) $a+b$ は $M$ 未満 
-  * $b+d$ で $M$ 以上なのだから、$c+d$ は $M$ 以上+  * (左) $b+d$ で $M$ 以上 => (右) $c+d$ は $M$ 以上
  
 よって、組み替えた後も $M$未満/以上という分類は成立している。 よって、組み替えた後も $M$未満/以上という分類は成立している。
  
-また、$a+c \ge a+b$、$b+d \ge c+d$ が成り立つので、最終的な $X$ の値も $X_左 \ge X_右$ となり、常に改善される。+また、$(左)a+c \ge (右)a+b$、$(左)b+d \ge (右)c+d$ が成り立つので、最終的な $Z$ の値も $Z_左 \ge Z_右$ となり、常に改善される。
  
 他のケースも、考えていくと同じ事が言える。 他のケースも、考えていくと同じ事が言える。
行 482: 行 497:
 残る問題は、 残る問題は、
  
-  * この分類が正しいのか(実際に$b+c$はちゃんと$M$未満か?)+  * この分類が正しいのか(たとえば$b+c$は実際に$M$未満か?)
   * 正しい分類が複数ある場合、どれが最小なのか   * 正しい分類が複数ある場合、どれが最小なのか
  
-2番目の問題から考える。 +2番目の問題から考える。仮に $M$ 未満の個数を1減らしてみる。
- +
-変化させられるのは、$M$ 未満と以上のペアの個数である。個数を決めればペアは決まる。仮に $M$ 未満の個数を1減らしてみる。+
  
           ,--,           ,--,
行 496: 行 509:
                 `--------------'                 `--------------'
                                              
-変化前と変化後で、変化後の全てのペアのスコアが、変化前のいずれかのスコア以下、ということが言えれば、$X$ は変化後の方が小さと言える。そしてそれは実際に言える。+$\mod{M}$ の条件を取り除いたときの考察と同様に、変化前と変化後で、変化後の全てのペアのスコアが、変化前のいずれかのスコア以下、ということが言いたい 
 +そしてそれは実際に言える。
  
   変化前          変化後   変化前          変化後
行 505: 行 519:
  
 よって、分類が正しく成立してるなら、$M$ 未満の個数はなるべく少ない方がよいと言える。 よって、分類が正しく成立してるなら、$M$ 未満の個数はなるべく少ない方がよいと言える。
-(厳密にるなら、項数 $N$ や変化前後の分類の個数について一般化する必要があるが)+(厳密に証明するなら、項数 $N$ や変化前後の分類の個数について一般化する必要があるが)
  
-分類が成立するとう前提のもと、$M$ 未満の個数が最も少ない境界を、2分探索で求める。+分類が成立して、$M$ 未満の個数が最も少ない境界を、2分探索で求める。 
 + 
 +$a_1,a_2,...$ をソート後、真ん中に境界を仮定して、分類の成立を調べる。 
 + 
 +  * 成立、$M$ 未満グループが不成立(和が $M$ 以上のペアが出来てしまう)なら左半分から境界を探索 
 +  * $M$ 以上グループが不成立(和が $M$ 未満のペアが出来てしまう)なら右半分から境界を探索 
 + 
 +両方のグループが同時に不成立となることは無い。仮に $M$ 未満グループから $a,b$、$M$ 以上グループから $c,d$ が不成立だったとすると、矛盾する。 
 + 
 +  小←        分類の境界       →大 
 +  ... a ... b ... | ... c ... d ... 
 +   
 +  ソート順: a <= b <= c <= d       =>  a+b <= c+d 
 +  成立条件: a + b >= M、c + d < M  =>  a+b >  c+d
  
 <sxh python> <sxh python>
programming_algorithm/contest_history/atcoder/2019/0323_agc032.txt · 最終更新: 2019/04/21 by ikatakos
CC Attribution 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0