O slideshow foi denunciado.
Utilizamos seu perfil e dados de atividades no LinkedIn para personalizar e exibir anúncios mais relevantes. Altere suas preferências de anúncios quando desejar.

ACPC 2018 Day3 G: 回文部分列 (Palindromic Subsequences)

297 visualizações

Publicada em

2018/9/21 会津大学プログラミング合宿 Day3 (北大セット) G 問題
※文字が見えない場合、ダウンロードするかフルスクリーンにしてご覧ください。(フルスクリーンにすると文字が消える問題に対処できるようです)

Publicada em: Tecnologia
  • Seja o primeiro a comentar

  • Seja a primeira pessoa a gostar disto

ACPC 2018 Day3 G: 回文部分列 (Palindromic Subsequences)

  1. 1. 会津合宿 2018 Day3 G 問題 回文部分列 (Palindromic Subsequences) 原案: tsutaj 問題文: tsutaj 解答: tsutaj・kazu・tsukasa_diary 解説: tsutaj 2018 年 9 月 21 日 tsutaj ACPC 2018 Day3 G 2018/9/21 1 / 12
  2. 2. 問題 回文部分列 (Palindromic Subsequences) 文字列 S が与えられる S の連続とは限らない部分文字列であって回文であるものは何種類? 制約 1 ≤ |S| ≤ 2, 000 S は英小文字のみからなる 例 acpc に含まれる回文部分列は 5 種類 a, c, cc, cpc, p それぞれの回文は unique に数える tsutaj ACPC 2018 Day3 G 2018/9/21 2 / 12
  3. 3. 回文の性質 回文はどんな性質がある? tsutaj ACPC 2018 Day3 G 2018/9/21 3 / 12
  4. 4. 回文の性質 回文はどんな性質がある? 右から読んでも左から読んでも同じ 文字列の前半を T、T を左右反転させた文字列を T′ とおくとき、回文 S は T + (中心の文字) + T′ の形をしている tsutaj ACPC 2018 Day3 G 2018/9/21 3 / 12
  5. 5. 方針 T としてあり得るものが何種類あるのかを知りたい tsutaj ACPC 2018 Day3 G 2018/9/21 4 / 12
  6. 6. 方針 T としてあり得るものが何種類あるのかを知りたい T′ は T を反転させたものなので、S を左から走査してできる部分列 と、S を右から走査してできる部分列が一致する状況を数え上げたい tsutaj ACPC 2018 Day3 G 2018/9/21 4 / 12
  7. 7. 方針 T としてあり得るものが何種類あるのかを知りたい T′ は T を反転させたものなので、S を左から走査してできる部分列 と、S を右から走査してできる部分列が一致する状況を数え上げたい T および T′ の終端の位置がわかれば、中心の文字としてあり得るも のの種類数も数えられる tsutaj ACPC 2018 Day3 G 2018/9/21 4 / 12
  8. 8. 方針 S の他に、S を反転させた文字列 S′ も用意 tsutaj ACPC 2018 Day3 G 2018/9/21 5 / 12
  9. 9. 方針 S の他に、S を反転させた文字列 S′ も用意 T および T′ を求めることは、S と S′ の共通部分列を求めることと 同じ! ただし区間被りに注意すること tsutaj ACPC 2018 Day3 G 2018/9/21 5 / 12
  10. 10. 共通部分列 2 つの文字列に対する共通部分列の種類数はどのように数え上げる? tsutaj ACPC 2018 Day3 G 2018/9/21 6 / 12
  11. 11. 共通部分列 2 つの文字列に対する共通部分列の種類数はどのように数え上げる? DP をしよう! 説明の都合上、2 つの文字列を X, Y と置く tsutaj ACPC 2018 Day3 G 2018/9/21 6 / 12
  12. 12. 共通部分列 2 つの文字列に対する共通部分列の種類数はどのように数え上げる? DP をしよう! 説明の都合上、2 つの文字列を X, Y と置く dp[i][j] := X の i 文字目、Y の j 文字目まで使ってできる共通部分列 の種類数 状態 dp[i][j] で考慮している共通部分列の末尾にアルファベット c を追 加するときは、X の i 文字目より後の c の中で最も近いもの・Y の j 文字目より後の c の中で最も近いものを選んで遷移すれば良い tsutaj ACPC 2018 Day3 G 2018/9/21 6 / 12
  13. 13. 共通部分列 2 つの文字列に対する共通部分列の種類数はどのように数え上げる? DP をしよう! 説明の都合上、2 つの文字列を X, Y と置く dp[i][j] := X の i 文字目、Y の j 文字目まで使ってできる共通部分列 の種類数 状態 dp[i][j] で考慮している共通部分列の末尾にアルファベット c を追 加するときは、X の i 文字目より後の c の中で最も近いもの・Y の j 文字目より後の c の中で最も近いものを選んで遷移すれば良い 次ページで詳しく解説 tsutaj ACPC 2018 Day3 G 2018/9/21 6 / 12
  14. 14. 共通部分列 dp[2][1] の状態から、共通部分列を 1 文字増やしたい 's' を増やしたい場合、どの s を持ってくればよいか? tsutaj ACPC 2018 Day3 G 2018/9/21 7 / 12
  15. 15. 共通部分列 こういうとり方もあり得るが・・・ tsutaj ACPC 2018 Day3 G 2018/9/21 8 / 12
  16. 16. 共通部分列 この方が余りが多くて余裕がある! 余りが多いと、より長い共通部分列を作れる可能性がある tsutaj ACPC 2018 Day3 G 2018/9/21 9 / 12
  17. 17. 共通部分列 この方が余りが多くて余裕がある! 余りが多いと、より長い共通部分列を作れる可能性がある なので、文字を増やす際は近いものを貪欲に取り、余りを増やしたほ うが良い この DP によって、共通部分列を unique に数え上げることができる tsutaj ACPC 2018 Day3 G 2018/9/21 9 / 12
  18. 18. 解法の流れ 回文部分列の数え上げは以下のように解ける tsutaj ACPC 2018 Day3 G 2018/9/21 10 / 12
  19. 19. 解法の流れ 回文部分列の数え上げは以下のように解ける 先ほどの共通部分列の DP をやる tsutaj ACPC 2018 Day3 G 2018/9/21 10 / 12
  20. 20. 解法の流れ 回文部分列の数え上げは以下のように解ける 先ほどの共通部分列の DP をやる dp[i][j] の中で区間として被らないものについて、dp[i][j]× (余った区 間内にあるアルファベットの種類数 +1) を計算して答えに足し合わ せる tsutaj ACPC 2018 Day3 G 2018/9/21 10 / 12
  21. 21. 解法の流れ 回文部分列の数え上げは以下のように解ける 先ほどの共通部分列の DP をやる dp[i][j] の中で区間として被らないものについて、dp[i][j]× (余った区 間内にあるアルファベットの種類数 +1) を計算して答えに足し合わ せる 余った区間内にあるアルファベットの種類数を掛けるのは、奇数長の回 文を数え上げるため 間に 1 文字挟むと奇数長回文になる tsutaj ACPC 2018 Day3 G 2018/9/21 10 / 12
  22. 22. 解法の流れ 回文部分列の数え上げは以下のように解ける 先ほどの共通部分列の DP をやる dp[i][j] の中で区間として被らないものについて、dp[i][j]× (余った区 間内にあるアルファベットの種類数 +1) を計算して答えに足し合わ せる 余った区間内にあるアルファベットの種類数を掛けるのは、奇数長の回 文を数え上げるため 間に 1 文字挟むと奇数長回文になる +1 するのは、偶数長の回文を数え上げるため 間になにも挟まないと偶数長回文になる tsutaj ACPC 2018 Day3 G 2018/9/21 10 / 12
  23. 23. 解法の流れ 回文部分列の数え上げは以下のように解ける 先ほどの共通部分列の DP をやる dp[i][j] の中で区間として被らないものについて、dp[i][j]× (余った区 間内にあるアルファベットの種類数 +1) を計算して答えに足し合わ せる 余った区間内にあるアルファベットの種類数を掛けるのは、奇数長の回 文を数え上げるため 間に 1 文字挟むと奇数長回文になる +1 するのは、偶数長の回文を数え上げるため 間になにも挟まないと偶数長回文になる 空文字列を誤って答えに足さないよう注意! 最後に −1 するか、例外処理するか、お好みで tsutaj ACPC 2018 Day3 G 2018/9/21 10 / 12
  24. 24. 解法の流れ 回文部分列の数え上げは以下のように解ける 先ほどの共通部分列の DP をやる dp[i][j] の中で区間として被らないものについて、dp[i][j]× (余った区 間内にあるアルファベットの種類数 +1) を計算して答えに足し合わ せる 余った区間内にあるアルファベットの種類数を掛けるのは、奇数長の回 文を数え上げるため 間に 1 文字挟むと奇数長回文になる +1 するのは、偶数長の回文を数え上げるため 間になにも挟まないと偶数長回文になる 空文字列を誤って答えに足さないよう注意! 最後に −1 するか、例外処理するか、お好みで 足しあわせた結果が答え tsutaj ACPC 2018 Day3 G 2018/9/21 10 / 12
  25. 25. 計算量 この解法の計算量は? tsutaj ACPC 2018 Day3 G 2018/9/21 11 / 12
  26. 26. 計算量 この解法の計算量は? 共通部分列 DP は「インデックス i より後に登場するアルファベット c の中で最も近いものはどれか」を前処理することで O(|S|2) 前処理は線形でも可能だし二乗でも可能 どちらを書いても構いません tsutaj ACPC 2018 Day3 G 2018/9/21 11 / 12
  27. 27. 計算量 この解法の計算量は? 共通部分列 DP は「インデックス i より後に登場するアルファベット c の中で最も近いものはどれか」を前処理することで O(|S|2) 前処理は線形でも可能だし二乗でも可能 どちらを書いても構いません 答えを足し合わせる時は、「指定区間内にアルファベットは何種類ある か」を前処理することで O(|S|2) 各アルファベットについて累積和を用意すれば、何種類あるかは O(1) 足し合わせるときに参照する場所の候補が O(|S|2 ) なので、この処理は 全体で O(|S|2 ) tsutaj ACPC 2018 Day3 G 2018/9/21 11 / 12
  28. 28. 計算量 この解法の計算量は? 共通部分列 DP は「インデックス i より後に登場するアルファベット c の中で最も近いものはどれか」を前処理することで O(|S|2) 前処理は線形でも可能だし二乗でも可能 どちらを書いても構いません 答えを足し合わせる時は、「指定区間内にアルファベットは何種類ある か」を前処理することで O(|S|2) 各アルファベットについて累積和を用意すれば、何種類あるかは O(1) 足し合わせるときに参照する場所の候補が O(|S|2 ) なので、この処理は 全体で O(|S|2 ) したがって問題全体で O(|S|2) で解ける! tsutaj ACPC 2018 Day3 G 2018/9/21 11 / 12
  29. 29. Writer 解・統計 Writer 解 tsutaj (C++・78 行・1985 bytes) kazu (C++・83 行・2329 bytes) tsukasa_diary (C++・60 行・1422 bytes) 統計 AC / tried: 11 / 15 (73.3 %) First AC On-site: acpc_aizulim (79 min) On-line: LLma (23 min) tsutaj ACPC 2018 Day3 G 2018/9/21 12 / 12

×