解説
この問題は、ゴールまでに必要な最小のコストを求めるため最短経路問題に見えますが、変化した順番によって辺のコストが変わるのが厄介です。
逆に、今まで変化した物質さえ確定すれば、スタートからある物質までに必要な最小のコストも一意に定まりそうです。
そこで、今の物質の他に、これまでどの物質に変化したかを記録することにします。
変化したか変化していないかはtrue/falseで表すことが出来るので、ビットで管理すると良さそうです。
今まで変化した物質の情報を表す整数をs,現在の物質をvとした場合
dp[s,v]を今まで変化した物質がsの場合の0からvまで変化させるときの最小のコストとします。
すると、fからtに変化させるときのdpの値は、
dp[s or 1<<t,t]=min(dp[s or 1<<t,t],dp[s,f]+必要なコスト)
となります。
必要なコストはdpと同様に触媒を持っているかの情報をビットで持てば求めることが出来ます。(物質の数は少し多いが、整数が7個ほどあれば表せる)
最初、手元にあるのは物質0なので、dp[1,0]=0それ以外の要素を非常に大きな数(今回の場合10^8程度あれば十分)で初期化し、
FOR I=1 TO (1<<N)-1
FOR J=0 TO N-1
WHILE 頂点Jから出る全ての頂点に対して
上記の式
触媒を更新
WEND
NEXT J
NEXT I
のようにループを回せば、答えはDP[ANY,1]の最小値になります。(ANYは任意の数)
与えられるデータの持ち方ですが、上のプログラムではある頂点から出る全ての頂点を求める必要があるため、隣接リストで持つと良いです。
以上のように、集合をビットを用いて表現した動的計画法(過去の解説参照
http://petitverse.hosiken.jp/community/petitcom/topic/?read=1504&ukey=0)はビットDPと呼ばれ、巡回セールスマン問題の厳密解を求める比較的現実的なアルゴリズムとして有名です。(ヘルドカープのアルゴリズムと呼ばれるらしい)