Educational DP Contest / DP まとめコンテスト Z - Frog 3
解法
番目の足場へ行く最小コスト
とします。すると、
となります。
これを式変形すると、
となります。は最後に足して問題ないことがわかります。
とすると、
という式になり、調べたいのは、
のの際の最小値
となります。
これは直線の式になっているので、
たとえばCHT アルゴリズム
で検索をすると下のような記事が、
http://satanic0258.hatenablog.com/entry/2016/08/16/181331
また、Li Chao Tree
で検索をすると下のような記事が出てきます。
https://smijake3.hatenablog.com/entry/2018/06/16/144548
あとは、これらのアルゴリズムを用いて、
でクエリを投げる(得られた最小値をとします)
の直線を追加する
という操作を繰り返すと、のクエリの答えに、を加えたものが答えになります。
のみ、クエリを投げずにの直線を追加します。
感想
上記のアルゴリズム達は、直線を管理するアルゴリズム、ということだけ知っていたので、もしかしてこれかな?と思い検索をかけるとぴったりハマったので嬉しかったです。
Educational DP Contest / DP まとめコンテスト Y - Grid 2
解法
包除原理を用いて解きます。
個以上の壁を通り、番目の壁に到達するような通り方の場合の数
とします。ここで、壁について、行、列の順で昇順ソートしておくと、番目の壁を通る際に、番目以降の壁を先に通ることはありえなくなるので、うまく計算することができます。
また、スタート地点を番目の壁、ゴール地点を番目の壁、とすることで、初期化はとすることができます。
ただし、
は、初めにソートしたときに満たすようになっています。
右側のコンビネーションの項は、番目の壁から番目の壁に行く行き方です。
これを計算すると、答えが
となるので、のの部分を、の2通りに集約することができます。こうすることで、計算量がにおさまり、
になります。
感想
包除原理は普段解けないことが多いのですが、割とスッキリ解けたのでよかったです。
Educational DP Contest / DP まとめコンテスト X - Tower
解法
現在、積まれているブロックの重さの総和をとします。
ここに、2種類のブロックを、どちらの順番で新しく下に置くかを考えます。
の方がより上にくる場合
の方がより上にくる場合
1つめの条件は、結局2つのブロックを乗せることにした時点で満たしていなければならないので、無視します。
ということで、それぞれの条件の2つ目を比較すると、
となり、とのうち大きい順番の方が、の許容範囲が大きくなります。
の場合、をの上に乗せたほうがよいです。
この条件を式変形すると、となるので、
結局はの昇順でブロックを並べると、その順番で上から積んでいくのが最善になります。
あとは、基本的にナップサックと同じで、
番目のブロックまで見て、重さの総和がになるようなブロックの選び方をしたときの、価値の総和の最大値
として、
(ただし、 もしくはの際は)
を計算すればよいです。
答えは、の最大値、初期化は全て0です。
感想
この問題で似たような考え方をしたので、あっさりと解くことができました。
が、証明は難しいです…(後付けで考えました)
ICPC 2019 Asia Yokohama Regional参加記
ということで、チーム CoprimE
として、ICPCのアジア予選に参加してきました。
チームメイトはTsuzu君、mi君です。
1日目
~リハーサル前
一部コーチの奢りです、わーい pic.twitter.com/vfkEgyrN1I
— ツバサ (@emtsu_ba) 2019年11月16日
コーチのご厚意で一部奢っていただきました。
来たぞー pic.twitter.com/xRgTb2FWRM
— ツバサ (@emtsu_ba) 2019年11月16日
リハーサル
Tsuzu君が環境構築、僕がA、mi君がBを読みました。
Aはやるだけなので僕がそのまま通しました。
Bはほぼ同じ問題を僕が解いたことがあったのですが、とりあえず2人も実装してみようということで実装しました。が、二人とも実装が詰まったので自分がバトンタッチして通しました。
Cは非想定らしい、解法っぽいものを残り5分ぐらいで思い浮かんだのですが間に合わず終了しました。
リハーサル後
観光をしました。
中華街にいた無限の競プロerさん達に別れを告げて横浜観光をする弊チーム pic.twitter.com/9RR3eY3iCI
— ツバサ (@emtsu_ba) 2019年11月16日
ABCにも出ましたが、Fが解けず黄色前半パフォだったため、黄色には届きませんでした。
m_tsubasaさんのAtCoder Beginner Contest 145での成績:197位
— ツバサ (@emtsu_ba) 2019年11月16日
パフォーマンス:2079相当
レーティング:1961→1973 (+12) :)#AtCoder https://t.co/v6ZsKLoX07
2日目
本番
コンテスト開始直前になって、急に開始時間が5分はやまりました。まわりを眺めると、okimotiチームのrisujirohさん(だったはず)がトイレにまだ行っていたようで、大変そう…と思いながら問題を解き始めました。
コンテスト開始後は、リハーサル同様Tsuzu君が環境構築、僕がA、mi君がBを読みました。
Aは自分がそのまま実装、BはTsuzu君が実装してACしました。
その後、まわりを眺めつつ、問題をE,G,Hに絞り進めていましたが、Hの実装をまわりのチームがACし始めた直後ぐらいに始めたにも関わらず、最後までバグを取り切ることができませんでした。
自分はコードを2回、1から書き、Tsuzu君も1回1から書き直していました…
結局、コンテスト後に試したところ、自分は1行を変えただけで通りました。
同時に進めていたGもバグを取り切れず、結局2完52位で終了しました。
コンテスト後
Googleブースにあった、入力例のサンプルのみが与えられてそこから問題をエスパーする、というものを最後までやっていました。最後まで解けなかった上答えが答えだったのでかなり悔しかったです…チームメンバーはいろいろなブースをまわって楽しんでいたようです、賢い。
3日目
オフィスツアーです。疲労もあり結構疲れていました…
ついた pic.twitter.com/9NUtPTF0QA
— ツバサ (@emtsu_ba) 2019年11月18日
ローストビーフしぬほど美味しかった
— ツバサ (@emtsu_ba) 2019年11月18日
#icpc2019yokohama pic.twitter.com/v5Qvh0Gkag
第二弾 pic.twitter.com/drYQmNzQRi
— ツバサ (@emtsu_ba) 2019年11月18日
https://twitter.com/emtsu_ba/status/1196283821005533184?s=20
— ツバサ (@emtsu_ba) 2019年11月18日
イルカショー、1番騒いで楽しんでいるのこるとんさん達のエリアと僕、yamadさんのエリアだった
— ツバサ (@emtsu_ba) 2019年11月18日
これは…?
— ツバサ (@emtsu_ba) 2019年11月18日
#icpc2019yokohama pic.twitter.com/pXHduYfLgE
(最後はMicrosoftさんを見に行ったわけではないです)
感想
強豪チームがバンバン問題を解いていく様子を生で見ることができたり、普段は行けないような場所に行けたりしたので楽しかったです。
コンテスト前に、普段競プロをあまりやっていない同学年の友達に声をかけてもらったり、コンテスト中に反応をしていてくれたみたいで嬉しかったです。が、きちんと練習をしていればもっと上を目指せるチームだったはずなので、応援してくれた方々や、国内予選を戦った他の早稲田のチームには申し訳ない気持ちでいっぱいです。
来年はチームがどうなるかまだまだわかりませんが、チャンスがあればまたアジア予選に出場し、今度こそ納得のいく成績を取れるようにしたいです…
今、自分の大学の1年生や2年生で競プロ活動が活発になっていて、精進量がずば抜けている人もちらほら見かけます。自分が現状全く精進をしていないのもあり、このままだと抜かされる(もう負け始めている?)気がしているのですが、だからといって後輩たちに枠を譲るつもりは全くないので、また1から頑張ろうと思います。
来年のICPC学内予選ではvivid_turtleとUHISHIROがバチバチやる予定です!(願望)乞うご期待!!
— かっつ (@_KKT89) 2019年11月17日
負けません。
最後に、ICPCの運営をしてくださった方々、誘った際に快く承諾してくださったTsuzu君とmi君、そしてコーチを引き受けてくださったryoissyさん、ありがとうございました。
Educational DP Contest / DP まとめコンテスト V - Subtree
解法
全方位木dpをします。
初めに頂点1が根である際の値を求めます。
を根とする部分木について、を黒で塗った際の部分木の塗り方
とすると、頂点の子の集合をとして、
となります。
を根とした際の求めるべき答え
とすると、
となります。
が求まっている際に、その子であるについての答えを求めるため、へシフトすることを考えます。
書き換えるべき場所は、とのみになります。
については、定義に基づいて計算すればよいので、を求めることのみ考えます。
となるので、あとはこれを計算すればよいのですが、愚直に計算をすると間に合いません。
ある数列について、を高速に計算する方法を考えます。
これは、累積和同様に数列の前方からの累積積と、後方からの累積積をあらかじめ計算しておくと、それぞれの累積積について、番目の手前の値をかけ合わせることで、前計算のみで、で計算することができます。
あとは、これを利用することで、dfsを行いつつ、根の付け替えを行い答えを求めることができます。
感想
全方位木の概要は知っていたので考察はすんなり進んだのですが、累積積を利用する部分を思いつくのが難しかったです…