Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

DP(編集距離)とDPの問題を解くコツ

2,380 views

Published on

2015/10/30 競技プログラミング練習会 動的計画法

Published in: Technology
  • Be the first to comment

  • Be the first to like this

DP(編集距離)とDPの問題を解くコツ

  1. 1. 競技プログラミング練習会 KMC 1回生 @utgw
  2. 2. 動的計画法(DP) ● DPで解ける問題の中から、自分が面白いと思ったものを紹介 ○ 編集距離(レーベンシュタイン距離) ○ 進捗管理に失敗して1つだけになった…… ● DPで解ける問題を解くコツ ○ 自分への戒めとして ○ 道に迷ったときのために ● スライド製作者はDPに疎くてとても厳しかった
  3. 3. 編集距離(レーベンシュタイン距離) ● http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DPL_1_E&lang=jp http://yukicoder.me/problems/610 ● 文字の挿入|削除|置換で一方を他方に変形するための最小手順回数を数えたもの ● 入力:2つの文字列 s1,s2 (1 <= |s1|,|s2| <= 100) ● 出力:編集距離 ● 例 ○ s1 = “apple”, s2 = “ape” -> “2” ○ s1 = “perl”, s2 = “pearl” -> “1”
  4. 4. 編集距離をDPで求める流れ ● dp[i][j]: 文字列s1,s2のそれぞれi番目、j番目までの編集距離 ● 明らかに dp[0][i] = i, dp[j][0] = j (i = 0,1,...,|s1|; j = 0,1,...,|s2|) ● dp[i][j] を求めるのに必要なのは、次の3つの値 ○ dp[i-1][j] ○ dp[i][j-1] ○ dp[i-1][j-1] 参考: http://d.hatena.ne.jp/naoya/20090329/1238307757
  5. 5. 編集距離をDPで求める流れ ● s1の(i-1)文字目までの文字列に1文字追加する場合 ○ dp[i][j] = dp[i-1][j] + 1; ● s2のj文字目を削除する場合 ○ dp[i][j] = dp[i][j-1] + 1; ● s1のi文字目とs2のj文字目が同じ文字になるように置換する場合 ○ dp[i][j] = dp[i-1][j-1] + cost; ○ ただし、 cost = s1[i-1] == s2[j-1] ? 0 : 1 ○ i文字目とj文字目が等しければ、コストはかからない
  6. 6. 編集距離をDPで求める流れ ● この3つのうち、最小となるものを代入すればよい ● cost = s1[i-1] == s2[j-1] ? 0 : 1 dp[i][j] = min({dp[i-1][j] + 1, dp[i][j-1] + 1, dp[i-1][j-1] + cost}) ● O(|S1||S2|) で求められる
  7. 7. int ld(string s1, string s2){ int dp[MAX_S+1][MAX_S+1]; int l1 = s1.size(), l2 = s2.size(); REP(i,l1+1) dp[i][0] = i; REP(i,l2+1) dp[0][i] = i; FOR(i,1,l1+1){ FOR(j,1,l2+1){ int cost = s1[i-1] == s2[j-1] ? 0 : 1; dp[i][j] = min({dp[i-1][j]+1, // Insertion dp[i][j-1]+1, // Deletion dp[i-1][j-1]+cost}); // Replace } } return dp[l1][l2]; }
  8. 8. DPで解ける問題を解くコツ 1. 与えられた問題が、DPで解ける問題だということを見抜く(重要) ○ 最大値・最小値を求める ○ 数え上げ ○ etc. 2. 適切なDPテーブルの定義を考える 3. 漸化式を考える 4. 合ってそうなのに通らない場合は ○ コードのミスを見直す(他人のコードを読むつもりで) ○ 2. 3. を見直す ○ 頑張って計算量を減らす(がんばって) 参考: http://shindannin.hatenadiary.com/entry/20131208/1386512864
  9. 9. おしまい ● ありがとうございました
  10. 10. 参考 ● プログラミングコンテンストチャレンジブック 第2版 ISBN: 978-4-8399-4106-2 ● 動的計画法が苦手な人が、動的計画法が超苦手な人へアドバイスしてみる http://shindannin.hatenadiary.com/entry/20131208/1386512864 ● 編集距離 (Levenshtein Distance) http://d.hatena.ne.jp/naoya/20090329/1238307757
  11. 11. おまけ:動的計画法と年収の関係について https://twitter.com/mayah_puyo/status/643053132994375680

×