25. 考察1
• 辞書順最小の定義より,以下の性質が分かる
– K 回以下の操作で,S を文字 a だけからなる文字列にする
ことが可能ならば⾧さを最小にするのがよい
• S に含まれる文字 a の個数と K の和が |S| 以上か調べればよい
– そうでない場合は,先頭から連続する文字 a の個数を最大
にするのがよい
• K = 2の例のように S 中に含まれる a を使うことで, a の挿入より
a への置換の方が先頭から連続する a の個数を増やせることがある
26. 考察2
• 先頭から連続する a の個数の最大値が,置換操作でも
挿入操作でも変化しないとき,どうするか?
• S = cacbxbyzzzz, K = 4 について考える
– 一文字目を a に置換することで,先頭から連続する a の
個数は最大 5 にすることが可能
– 残り 3 回,どのように置換,挿入を行うか?
27. 考察2
• 先頭から連続する a の個数の最大値が,置換操作でも
挿入操作でも変化しないとき,どうするか?
• S = cacbxbyzzzz, K = 4 について考える
– 一文字目を a に置換することで,先頭から連続する a の
個数は最大 5 にすることが可能
– 残り 3 回,どのように置換,挿入を行うか?
• 3 文字目の c を a に置換,その後先頭に a を 2 回挿入するのが最適
1 2 3 4 5 6 7 8 9 10 11
c a c b x b y z z z z
c b x b y z z z z
b x b y z z z z
x b y z z z z
28. 考察2
• 先頭から連続する a の個数の最大値が,置換操作でも
挿入操作でも変化しないとき,どうするか?
• S = cacbxbyzzzz, K = 4 について考える
– 一文字目を a に置換することで,先頭から連続する a の
個数は最大 5 にすることが可能
– 残り 3 回,どのように置換,挿入を行うか?
• 3 文字目の c を a に置換,その後先頭に a を 2 回挿入するのが最適
• 候補となる i (3≦i≦5) 文字目を先頭とする接尾辞のうち
辞書順最小のものを選ぶのが最適ということ
1 2 3 4 5 6 7 8 9 10 11
c a c b x b y z z z z
c b x b y z z z z
b x b y z z z z
x b y z z z z
29. 部分点 3: ( |S| ≦ 1,000)
• 文字 a だけからなる文字列が作れるならば
可能な限り削除を行い⾧さ最小の文字列を作る
• 先頭から連続する文字 a の個数が最大になるように,
先頭から a 以外の文字を a に置換する
• 先頭から連続する文字 a の個数が同じになるような
範囲では,選べる接尾辞のうち最小のものを選ぶ
• 文字列の比較に O(|S|),最大 O(|S|) 回比較を行うので,
全体の計算量は O(|S|2)
31. 満点解法まとめ
• 文字 a だけからなる文字列が作れるならば
可能な限り削除を行い⾧さ最小の文字列を作る
• 先頭から連続する文字 a の個数が最大になるように,
先頭から a 以外の文字を a に置換する
• 先頭から連続する文字 a の個数が同じになるような
範囲では,選べる接尾辞のうち最小のものを
接尾辞配列に従って選ぶ
• 全体の計算量は O(|S|)
35. 考察1
• A と B の要素の総和は常に一定
– ΣA = ΣBのとき,ΣAΣBが最大となる
– A から B へ移動した要素の総和を a, B から A へ移動した要
素の総和を b とすると,交換したあとの得点は
(ΣA – a + b)(ΣB – b + a)で表せる
• K 回の交換操作で出来る限り ΣA とΣB を近づけたい
36. 考察2
• A から B へと移動した要素が k 個のとき,
B から A へと移動した要素は常に k 個
– そうでないとすると,交換という操作に矛盾
• K 回の操作で, A から B へ何個移動させられるか?
– K = 1: 1
– K > 1: 0, 1, 2, …, min(N, M, K)
• K > 1のとき, 0 以上 min(N, M, K) 以下の任意の個数を移動可能
• 交換操作は以下の 3 種類で考えればよい
– もともと A にあった要素を新たに 1 個移動させる
– もともと A にあった要素を B から A へ 1 個移動させる
– もともと A にあった要素同士を交換する
• N = 1, M = 1 のときは成り立たないが,あまり気にしなくてよい
37. 部分点2: (max(Ai, Bj) ≦ 55)
• 動的計画法を用いる
– ΣA が定まると ΣB も定まることに着目する
– dp(i, j) = B から A に i 個移動させる必要がある時の A の
要素の総和が j であるような操作はあるか?
• 典型的なナップサック問題
– A の要素を詰め終わったあと, i > min(N, M, K) である
dp(i, j) を全て偽にする
• min(N, M, K) より多くの要素を交換することは出来ない
– B の要素を詰めたあと,dp(0, x) が真である x について
x(C – x) の最大値を調べればよい
• ここで C はΣA + ΣB とする
• 計算量はO((N + M)2max(ΣA))
38. 満点: (max(Ai, Bj) ≦ 22,222)
• bool 値を返すようなDPは状態数を削減可能なことが
ある
• dp(j) = A の要素の総和が j であるような, B から A に
移動させる必要がある個数の集合,とする
• 部分点解法のdp(i, j) の i が取りうる値の集合(1, 2, 3, …, min(N, M, K))が
返り値になっている
• i 番目のbitが 1 ならば部分点解法の dp(i, j) が真であることに対応
• min(N, M, K) ≦ 55 より 64 bit符号付き整数の範囲に収まる