難易度評価

難易度を1〜10段階で評価できます。投票はあとから変更・取り消しできます。

難易度(投票) 未投票 (0票)

投票の分布

まだ投票はありません。

  1. Lv.10票
  2. Lv.20票
  3. Lv.30票
  4. Lv.40票
  5. Lv.50票
  6. Lv.60票
  7. Lv.70票
  8. Lv.80票
  9. Lv.90票
  10. Lv.100票

難易度の目安を見る ↗

ログインして難易度を投票

外部サイトへ移動します

リンク先の URL を確認してから開いてください。

別タブで開く

Shortest Balanced Walk

作成者 webp

難易度(作成者設定) Lv.5

難易度(投票) 未投票 (0票)

実行時間制限
3 秒
メモリ制限
512 MiB

解説

解法 11

空文字列に以下の 22 種類の操作を 00 回以上繰り返し行うことで任意の正しいかっこ列を作ることができます。

  • 先頭に (、末尾に ) を加える
  • 先頭か末尾に空でない正しいかっこ列を連結する

これを利用して、次のように dp\text{dp} を定義します。

  • dpu,v≔\text{dp}_{u,v} \coloneqq 頂点 uu を始点、頂点 vv を終点とする良いウォークの長さとしてありえる値の最小値

まず dpu,v={0u=v∞u≠v\text{dp}_{u,v}=\begin{cases}0 & u=v\\\infty & u \ne v\end{cases} と初期化します。

dpu,v\text{dp}_{u,v} から、次のように遷移できます。

  • 頂点 uu と頂点 u′u' の間に ( が書かれた辺があり、頂点 vv と 頂点 v′v' の間に ) が書かれた辺があるとき、dpu′,v′=min⁡(dpu′,v′,dpu,v+2)\text{dp}_{u',v'}=\min(\text{dp}_{u',v'},\text{dp}_{u,v}+2)

  • u′≠uu' \ne u を満たす u′u' について、dpu′,v=min⁡(dpu′,v,dpu′,u+dpu,v)\text{dp}_{u',v}=\min(\text{dp}_{u',v},\text{dp}_{u',u}+\text{dp}_{u,v})

  • v′≠vv' \ne v を満たす v′v' について、dpu,v′=min⁡(dpu,v′,dpu,v+dpv,v′)\text{dp}_{u,v'}=\min(\text{dp}_{u,v'},\text{dp}_{u,v}+\text{dp}_{v,v'})

これらの遷移を、確定した dp\text{dp} の値が小さい順に処理することで、ダイクストラ法と同様に最小値を求めることができます。

最終的に、 dp1,N\text{dp}_{1,N} がこの問題の答えです。 dp1,N=∞\text{dp}_{1,N}=\infty の場合、良いウォークは存在しません。

計算量は、 dp\text{dp} の遷移に優先度付きキューを用いることで O((N3+M2)log⁡(N3+M2))O((N^3+M^2)\log(N^3+M^2)) になります。

解答例 (C++)

解答例 (Python)

解法 22

かっこ列の 深さ を、かっこ列に含まれる ( の数から ) の数を引いたものと定義します。

かっこ列 XX が正しいかっこ列であることは以下の両方が成り立つことと同値です。

  • XX の任意の接頭辞 YY について、 YY の深さは 00 以上
  • XX の深さは 00

これを利用して、次のように dp\text{dp} を定義します。

  • dpv,s≔\text{dp}_{v,s}\coloneqq 頂点 11 を始点、頂点 vv を終点とし、変換後の数列の総和が ss となるウォークの最短長

まず、 dpv,s={0(v,s)=(1,0)∞(v,s)≠(1,0)\text{dp}_{v,s} = \begin{cases}0 & (v,s)=(1,0)\\\infty&(v,s)\ne(1,0)\end{cases} と初期化します。

dpv,s\text{dp}_{v,s} から、次のように遷移できます。

  • 頂点 u,vu,v の間に ( が書かれた辺があるとき、dpu,s+1=min⁡(dpu,s+1,dpv,s+1)\text{dp}_{u,s+1}=\min(\text{dp}_{u,s+1},\text{dp}_{v,s}+1)
  • s>0s \gt 0 かつ、頂点 u,vu,v の間に ) が書かれた辺があるとき、dpu,s−1=min⁡(dpu,s−1,dpv,s+1)\text{dp}_{u,s-1}=\min(\text{dp}_{u,s-1},\text{dp}_{v,s}+1)

最終的に、 dpN,0\text{dp}_{N,0} がこの問題の答えです。dp1,N=∞\text{dp}_{1,N}=\infty の場合、良いウォークは存在しません。

ウォークに対応するかっこ列の深さは大きくなり続けることがあるため、上限 SS を設定して遷移を打ち切る必要があります。

S≥N−2S \geq N-2 で十分な可能性があるとしていましたが、以下の記事で S=N−2S=N-2 が正当ではなく、 S=2N−1S=2N-1 が正当であることの証明を公開してくださいました。ありがとうございます。

Shortest Balanced Walk 解法 2 の正当性 (by wasd314)

証明の概要

良いウォークが存在するならば、以下が成り立ちます。

  • 頂点 11 を始点、頂点 NN を終点とする偶数長のウォークが存在する
  • 頂点 11 を端点としてラベル ( を持つ辺がある
  • 頂点 NN を端点としてラベル ) を持つ辺がある

逆に、これらが成り立つとき、偶数長のウォークの先頭と末尾に辺を追加して良いウォークを構成することができます。そのようにして構成される良いウォークの長さを見積もると 4N−24N-2 以下になるので、 S=2N−1S=2N-1 で十分です。

計算量は O(SM)O(SM) です。

解答例 (C++)

解答例 (Python)

ユーザー解説

ユーザー解説を書く

ユーザー解説はまだありません。