Problem F Two-finger Programming 解答:寺島・林崎 英文:寺島・吉野 解説:寺島 解答状況 Submitted : 1 (1 teams) Solved : 1 First Accepted : 211 min (echizen.bat) 問題概要 プログラムの変数名の付け替え できるだけ短くしたい 使っていい文字は’f’,’j’のみ プログラムの文法 重要なのは2点 字句解析は極めて簡単 構文解析はほとんど不要 ‘{‘’}’の対応と識別子だけ見れば十分 解法(1) 貪欲法 最大に割り当てられる変数集合から短い名前を 割り当てていく 独立したスコープの変数には同じ名前を割り当て られる点に注意 貪欲法(step 1) スコープの最大割り当て数 = max(max{スコープに属する変数の頻度}, sum{サブスコープの最大割り当て数}) 6 : ga 4 : gb 6 > 3+2 {ga}にfを割り当て サブスコープ 3 : saa 2 : sab 2 : sba 貪欲法(step 2) スコープの最大割り当て数 = max(max{スコープに属する変数の頻度}, sum{サブスコープの最大割り当て数}) 6 : f 4 : gb 4 < 3+2 {saa,sba}にjを割り当て サブスコープ 3 : saa 2 : sab 2 : sba 貪欲法(step 3) スコープの最大割り当て数 = max(max{スコープに属する変数の頻度}, sum{サブスコープの最大割り当て数}) 6 : f 4 : gb 4>2 {gb}にffを割り当て サブスコープ 3 : j 2 : sab 2 : j 貪欲法(step 4) スコープの最大割り当て数 = max(max{スコープに属する変数の頻度}, sum{サブスコープの最大割り当て数}) 6 : f 4 : ff 0<2 {sab}にfjを割り当て サブスコープ 3 : j 2 : sab 2 : j 貪欲法(step 5) スコープの最大割り当て数 = max(max{スコープに属する変数の頻度}, sum{サブスコープの最大割り当て数}) 6 : f 4 : ff サブスコープ 3 : j 2 : fj 2 : j 解法(2) DP スコープの割り当て順序を求める サブスコープの割り当て順序をまとめる 各サブスコープのi番目の変数集合を同じ名前を割り当てる 変数集合とする そのスコープに属する変数を出現頻度でソートし, マージする 短い名前から順に割り当てる DP 6 : ga 4 : gb f j ff fj <= <= <= <= 6 5 4 2 : : : : ga saa,sba gb sab マージ サブスコープ 3 : saa 2 : sab 2 : sba 5 : saa,sba 2 : sab サブスコープをまとめる 特殊な扱いが必要な例 IF(hoge) { VAR foo; foo = 1; } hoge = 0; VAR bar; bar = hoge; IF(j) { VAR f; f = 1; } hoge = 0; VAR f; f = hoge; 同じ変数名を 使用可能 暗黙のスコープ 特殊例への対処 変数宣言でスコープを作る 2. サブスコープが閉じた直後にスコープを作る 3. サブスコープが閉じた後の変数宣言でスコープ を作る 1. 暗黙のスコープ IF(hoge) { {VAR foo; foo = 1; }} hoge = 0; {VAR bar; bar = hoge; } IF(hoge) { VAR foo; foo = 1; }{ hoge = 0; VAR bar; bar = hoge; } IF(hoge) { VAR foo; foo = 1; } hoge = 0; {VAR bar; bar = hoge; } 計算量 O(n log n + m) n変数,mスコープ 暗黙のスコープへの対処を2or3で 割り当て順序をまとめる処理をn回に抑える DP, まとめる先のほうが小さければswapすることで可能 この問題ではO(m n log n)で十分
© Copyright 2024 ExpyDoc