diverta 2019 Programming Contest 2-D:Squirrel Merchant

方針立ってから時間かけ過ぎた...。

解法

 まず1つの金属について考える。例えばg_A \lt g_Bなら、Aでどんぐりを金にして、Bで金をどんぐりにするという行為以外ありえない。このように不等号の向きを見れば、ある程度取るべき行動が確定する。金属の種類の違いを無視すれば、3つの不等号の向きの組み合わせは4通りなので、これで場合分けをし、全探索をすることを考えよう。g,s,bの3種類の金属をまとめてmを書くことにする。

  1. 3種類すべてm_A\leq m_Bのとき、取引所Aで金をi個、銀をj個買うと決めると、銅を買う個数も勝手に決まる。よって、i,jについて全探索してO(N^2)となる。
  2. 3種類すべてm_A\geq m_Bのとき、1の場合と同様にすればよい。
  3. m_A \leq m_Bとなる金属が2種類のとき、取引所Aでその2種類の金属をいくつか買い、取引所Bでどんぐりにした後、m_A \geq m_Bである金属を買えるだけ買い、取引所Aでその金属をすべてどんぐりにするという行動を考えればよい。したがって、最初に取引所Aでm_A \leq m_Bとなる2種類の金属をそれぞれいくつ買うかを決めることでO(N^2)の全探索が可能となる。
  4. m_A \leq m_Bとなる金属が1種類のとき、取引所Aでその金属を買えるだけ買い、取引所Bでその金属をどんぐりにしてから、m_A \geq m_Bである2種類の金属をうまく買って、取引所Aですべてどんぐりにするという行動を考えればよい。全探索すべきは、取引所Bでの金属の買い方だが、これは片方を何個買うかを決めればよいので、取引所Bについた時点でのドングリの個数がネックになる。これはO(N\max(ga,sa,ba))であり、全探索して間に合う。

これで問題を解くことができた。

実装

Submission #5936228 - diverta 2019 Programming Contest 2
算数パートが注意が必要で6WA...。この実装は「ある金属を買うのに使うどんぐりの数」をi,jとしているので参考にする場合は注意を...。

ナップサックdpでできるらしい。類題を解いたことがあったのに見えなくて悲しかった。