ABC054 D Mixing Experiment
頑張って実装したので記事にするぞ。最近更新頻度高いし競プロ頑張ってる感がある*1。
D: Mixing Experiment - AtCoder Beginner Contest 054 | AtCoder
問題概要
N種類の薬品のうちいくつかの薬品を購入する。薬品iにはタイプAの物質を グラム、タイプBの物質を グラム含んでおり、価格 円で売られている。
タイプAの物質とタイプBの物質の混合比が となるのに必要な最小予算を求めよ。
制約
DP解法1
求めるものは「物質の重さの比が となるのに必要な最小予算」なので、購入するそれぞれの物質の重さが最終的にわかればよい。よって、
dp[i][j][k]:=薬品 i まで見たときに、購入するタイプAの物質が合計 j グラム、タイプBの物質が合計 k グラムとなる最小費用
という配列をつくる。
j : k = となるdp[n][j][k]の最小値が求める最小費用。
計算量は。
Submission #1123367 - AtCoder Beginner Contest 054 | AtCoder
DP解法2
さっきのDP解法よりさらに計算量を落とすことができる。
(タイプAの物質の合計の重さ):(タイプBの物質の合計の重さ)=:
となれば良いので、
(タイプAの物質の合計の重さ) * - (タイプBの物質の合計の重さ) * = 0
となる最小費用をもとめればよい。よって、
dp[i][j]:=薬品 i まで見たときに、「購入するタイプAの物質の合計の重さと の積」と「購入するタイプBの物質の合計の重さと の積」の差が j のときの最小費用
という配列を作り、dp[n][0]が答えとなる(ただし、このままだとjは負の値をとることがあるので、jの値はずらす必要がある)。
計算量は *2。
Submission #1121081 - AtCoder Beginner Contest 054 | AtCoder
DP解法3
もう一つ別の解法があるのを見つけたので紹介だけ(参考サイト:ABC054-D「Mixing Experiment」 | クリエイティヴなヴログ)。
計算量はさっきのDP解法2と変わらないけど、やりかたが違う。
各薬品 i について、
d[i]:= * - *
を最初に求めておく。そのあと、
①d[i]=0となる の最小値を求める
②d[i]<0となるものとd[i]>0となるものをいくつか選び、和が0になるものの最小予算を求める(ここでDPを使う)
①と②のうち小さいほうが答えとなる(詳しい解き方はリンク先をみてください)。
半分全列挙
半分全列挙は昔に一度だけやったことがあるけど*3、復習しないので覚えてなかった(ので昔のコードを見ながら思い出しつつやった)。
半分全列挙は、まず半分にわけて、それぞれでありえる組み合わせを全列挙して、うまくmergeして答えを求める方法。名前そのまま。
計算量は、半分にわけて全列挙するところが で、mergeするところが なので全体で *4。
Submission #1128677 - AtCoder Beginner Contest 054 | AtCoder
感想
コンテスト中に通したかった……(そもそも全探でしようとしてたのでダメ)
ひとつの問題でいろいろな解き方ができるのは本当におもしろいし楽しいなあ。
同じ問題をずっと解いてるからsolvedが増えない><
— リサさんになりたいbot (@wk1080id) 2017年2月19日
でもいろいろな解法で考察することで実力がつくと信じてる!
*1:と書き始めた当初は思っていたが、記事が完成するのに1週間近くかかったのでダメ
*2:配列の大きさで考えると になる
*3:C: 無駄なものが嫌いな人 - AtCoder Regular Contest 017 | AtCoder
*4:この書き方だと某警察につかまりそう。 が正しいのだと思うけど、それではでうまくいくことがわからないし…。