ABC149 E - Handshake
解法
明らかに、得点の和が高いペアから順番に握手をしていくのが最適です。
ある得点が達成できるとすると、明らかに未満の任意の得点は、全く同じ手を選ぶことで達成でき、達成できないときは以上の得点はどう頑張っても達成できないので、
- 以上の得点を達成できるか
について単調性が存在します。
このについて二分探索をしたいのですが、うまくいきません(僕はいきませんでした)。ので、少し見方を変えます。
得点の和が高いペアから順番に握手をしていくのが最適だったので、ある得点について、
- 以上となるペアについては握手を行い、未満となるペアについては握手をしない
という区切り目が存在するはずです。
以上となるペアの個数が個以上になると、回握手することができます。
以上となるペアの個数についても、が減少すれば個数が増加し、単調性が存在しています。ので、
- 以上となるペアの個数が以上になる
ような、最大のを二分探索で求めることができます。
すると、その以上のペアの総和を求めればよいです。
片手がのとき、もう片方の手は、以上のを選ぶことができます。このの個数は、が降順ソートされていれば、二分探索で求めることができます。
これにより、ペアの個数を求めることができました。
総和についてもほぼ同様で、からまでの総和と、の総和を全てのについて足したものになります。
これは、後者についてはそのまま個数をかければよく、前者については累積和をあらかじめ計算しておくことで、高速に計算することができます。
あとは、コーナーケースである、
- 以上となるペアの個数がぴったりではなかった場合
についての差分を計算すればよいです(サンプル2参照)。
得点の和が以上となるペアは個未満になってしまうはずなので、今以上となるペアの個数が個あるとしたときに、総和から除くべき個のペアは、得点がとなっているものについてです。
ということで、を、全体の総和から引いてあげれば求める答えとなります。
感想
見るからに二分探索をしたいなぁ、と思っていたのですが、うまく二分探索をする方法を考えるのに詰まってしまいました。
見方の変え方が課題です。
ARC050 B - 花束
解法
個の花束を作成できるかどうか、を調べます。
まず、2種類の花束どちらも、1つの花束につき少なくとも1本使用することになるので、最低本ずつ使用することになります。
この部分を除くと、
赤い花を本使用する
青い花を本使用する
の2通りの操作どちらかを行うことで、1つの花束を作成することができます。
ので、結局、
であれば、個の花束を作成することができます。
この条件を調べて、個の花束を作成することができるとわかったとき、個未満の花束は明らかに作成することができます。
ということで、単調性が存在するため、上の条件を満たす最大のを二分探索で求めれば答えとなります。
感想
個数を決め打ち、どちらか片方のコストを0にして考えやすくする、といったよくある考え方が詰まっている気がします。
ARC044 B - 最短路問題
解法
頂点1が距離0でない場合や、頂点1以外が距離0である場合は、明らかに答えが0になるので処理しておきます。
それ以外のグラフについて考えます。
あらかじめ、距離がの頂点の個数をそれぞれカウントしておきます。
距離がである頂点は、距離がである頂点、である頂点、である頂点に向けて辺を張ることができます。である頂点との辺は、距離がである頂点から張る辺について考慮するときに計算すればよいので、距離がである頂点について考えるとき、の頂点との頂点に向けて張る辺についてのみ計算していきます。
距離の頂点に向けての辺の張り方
距離の頂点を1つ選びます。すると、この頂点は、距離がである頂点のうちすくなくとも1つの頂点に向けて辺が張られていなければなりません。
今選んだ頂点と、個の頂点との辺の張り方は、通りありますが、この中で選んではいけないパターンは、どこにも辺が張られていないパターンただ1つです。
ということで、距離の頂点1つに対し、距離の頂点との辺の張り方は通りとなります。
これが、個の頂点について同じことが考えられるので、最終的に距離の頂点との頂点についての辺の張り方は、
通り
です。距離の頂点同士を結ぶ辺の張り方
距離の頂点同士を結ぶ辺の張り方は、通りです。今回は、全ての辺について、張る、張らないの2パターンを自由に選べます。
ということで、
通りの張り方が存在します。
ということで、の最大値をとして、
が答えとなります。
AOJ 2402 - 天の川
解法
任意の五芒星から別の五芒星に向かう際に通る最短距離さえ計算できれば、あとはベガからアルタイルに向けてダイクストラ法で最短経路を計算すればよいです。
五芒星は5本の線分でできています。ということで、2つの五芒星の最短距離を調べる際は、それぞれ5本の中から1本ずつ線分を取り出し、2本の線分同士の最短距離を計算して、25通りの取り出し方の中で最も小さいものを距離とすればよいです。
ということで、2本の線分同士の距離を求めることができればいいことになりました。
2本の線分同士の最短距離は、少なくともどちらか片方の線分については端点が選ばれます(片方の線分を点のあつまりとみなし、もう一方の線分との距離が最短になる点を探していくとどちらか一方は端点になります)。
ということで、4つの端点に対し、点と線分の距離を求めてあげれば、その中の最小値をとってあげることで、線分同士の最短距離を求めることができます。