以下の内容はhttps://ngtkana.hatenablog.com/entry/2024/05/24/235658より取得しました。


yukicoder No.417 チューリップバブル の $O(NM)$ 時間解法

問題

No.417 チューリップバブル - yukicoder

解法

この解法は 木上のナップサック問題 #アルゴリズム - Qiita の「応用」で言及されているものと全く同じだと思います。↓でご指摘いただきました。

制約付きのナップサック問題への言い換え

まず各街 $i$ について

  • 重量:親側の辺 $e$ の長さ $C _ e$
  • 価値:税収 $U _ i$

で定まる荷物が与えられれれて、

  • 重量の合計が $M / 2$ 以下である
  • 採用した荷物全体の集合が、村 $0$(木の根)を含むある連結グラフの節点全体の集合になっている

という制約条件のもと、採用した荷物の価値の合計の最大値を計算する問題です。

このナップサック問題の解き方

以降ナップサック問題の「解配列」といえば、$M / 2$ 以下の全ての非負整数 $i$ について、重量の合計が $i$ 丁度であるという制約のもと価値の最大値(解なしならば $-\infty$)を格納するものを指します。

次の仕様を持つ関数 $\mathtt{dfs}(x, \mathtt{dp})$ を構成しましょう。この関数に $\mathtt{dfs}(0, [0, -\infty, -\infty, \dots])$ を渡すとほしかった解配列が手に入ります。

  • 入力
    • 木の節点 $x$
    • もとの問題に更に次の制約を加えたナップサック問題の解配列 $\mathtt{dp}$
      • pre-order において $x$ より前の節点に対応する荷物しか使ってはいけない
      • $x$ の祖先の荷物は全て使わなければならない
  • 出力
    • もとの問題に更に次の制約を加えたナップサック問題の解配列
      • post-order において $x$ と同じかそれより前の節点に対応する荷物しか使ってはいけない
      • $x$ の祖先の荷物は全て使わなければならない

入出力要件

この関数は次のように再帰的に実装できます。

  1. $\mathtt{dp}$ に節点 $x$ に対応する荷物を必須荷物として加えた解配列 $\mathtt{next}$ を構築します
  2. $x$ の各子 $y$ に対して $\mathtt{next} = \mathtt{dfs}(y, \mathtt{next})$ をします
  3. $\mathtt{dp}$ と $\mathtt{next}$ の各点 max を返します

提出

https://yukicoder.me/submissions/983511

比較

公式解説、kmjp さんの解説、mayuko_ さんの解説、はまやんはまやんさんの解説(全て参考文献にリンクあり)はどれも、各節点で解配列のマージ(min-plus convolution)を行っていて、$Θ(nm ^ 2)$ 時間かかるので、この記事の解法の方のほうがより高速なはずです。

参考文献




以上の内容はhttps://ngtkana.hatenablog.com/entry/2024/05/24/235658より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14