競技プログラミング日記

主に AtCoder の記事です

AtCoder Beginner Contest 146F

ABC146F

最短を求める部分と,lex order 最小を求める部分を,分けて考える.

辞書順最小を求める. これは,全ての候補を求めてソートするのは間に合わないので, 自分で構成したほうが良い. 先頭から小さい順に決めるのが理想だが, それだとゴールできる min cost かどうかが分からない.
そこで,ゴールから逆算していく. ゴールから逆算しながら,可能な範囲で大きい歩数で進むのが良い. これは,進めるマスが \([1,M]\) だから可能な貪欲法.

補足
Lex order で最小でないならば,貪欲で決めたものが最適でない. よって,貪欲を決めながら lex order の最小が求まる.



別解
素直に解くなら,区間更新min の segtreeがあれば良い. 遅延伝搬segtree で出来るらしい? 和に関する区間更新なら,imos 法を使って点更新でも可能だが.

使っている記号,マクロ等 "https://ecsmtlir.hatenablog.com/entry/2022/12/23/131925"

int main() {
  ll n, m ;
  cin >> n >> m;
  string s; cin >> s;
 
  ll cu = n;
  vll ans;
  ans.push_back(cu);
  while(cu != 0){
    bool f = false;
    for(ll i = max(0ll,cu-m); i < cu; i++) {
      if(s[i] == '0'){
        cu = i;
        f = true;
        ans.push_back(i);
        break;
      }
    }
    if(!f){
      cout << -1 << endl;
      return 0;
    }
  }

  reverse(all(ans));
  rep(i, ans.size()-1){
    cout << ans[i+1] - ans[i] << " ";
  }
  return 0;
}