辛うじて全完したが、最後の問題の正しい解法がわからなかった。
K - 急ぎ旅
最短経路DAGを作ってからDPした。
ダイクストラと同時にできるらしい。確かに。
L - たくさんの最小値
最小値の列挙は遅延セグメント木上を二分探索すればできる。いつもこの方針でやっていて、想定解のようにノードに持たせる情報を増やすやり方でやったことがない。後者でないと難しい設問ってあるんだろうか。
M - 分割
明らかに最小費用流だと思ったが、グラフの作り方で長時間かけてしまった。
辺の下限流量を決めて変形するイメージで作った。まず、整数Aiを表す各位置iをiin,ioutに分割する。
- Sからioutに容量1、コスト0の辺を張る
- iinからTに容量1、コスト0の辺を張る
- ioutからTに容量1、コストCの辺を張る
- i<jであるすべてのjについて、ioutからjinに容量1、コスト∣Ai−Aj∣の辺を張る
想定解は「通ってほしい辺」のコストを−∞にしてから変形する考え方のようだった。こちらは全然考えたことがなかった。
N - モノクロデザイン
JOI 2012 春合宿 - fortune_telling
O - コンピュータ
(Bi)が狭義単調増加の場合が解ければよい。また、世界にはB1,...,BN円のコンピュータしか存在しないとしてよい。
dp[x]=x日目でちょうどコンピュータを買い替えなければならない場合の最大所持金額
とする。x日目に買えるコンピュータは、所持金以下であるような最大価格のコンピュータをrとしてBx,Bx+1,...,Brのいずれかであり、Byを買うとすると遷移はdp[y+1]:=max(dp[y+1],dp[x]+Ax+1+Ax+2+...+Ay+1−By)。Ax+1+Ax+2+...+Ay+1の部分を累積和で計算すると、このDPはO(N2)である。
o(N2)にする方法がわからなかった。試しに、買うコンピュータをxかrだけにしたものを投げると半分以上は通る。それならと思って両端から2000個程度(x,x+1,...,x+2000とk−2000,...,k−1,k)の遷移に限定してみたらACした。
解説を見た。
dp[x]= コンピュータxを買った時点での支出の最小値
とする。コンピュータpを買ってから次に買うコンピュータとしてxを選べる必要十分条件はA1+...+Ap+1−dp[p]≥Bxであること。これが成り立つようなpについて、dp[x]:=minpdp[p]+Bxと更新すればよい。
実装としては、range minを載せた平衡二分木のキーA1+...+Ap+1−dp[p]に値dp[p]を対応させておけば、キーがBx以上のノードについてのdp[p]の最小値を高速に求められる。
Oは今までのPASTで一番難しく感じた。