zoukankan      html  css  js  c++  java
  • Codeforces 1383E Strange Operation

    https://codeforces.com/contest/1383/problem/E

    本文是我对 tourist 的解法的解释。

    题目大意

    给定一个01串 $S$,长度是 $n$。定义操作:将串中相邻两数变成二者的最大值。每次操作过后串长减少 $1$。

    $00 o 0$
    $01 o 1$
    $10 o 1$
    $11 o 1$

    试问经过至少 $0$ 次,至多 $n - 1$ 次操作之后可以得到多少种不同的01串。

    分析

    首先注意到原串中的1不可能全部消除。
    用 $f(S)$ 表示01串 $S$ 经过至多 $|S|-1$ 次操作过后可以得到的不同 01 串的数量。
    考虑两种情况:

    1. $S$ 全是 0。答案是 $|S|$。
    2. $S$ 不全是 0。设 $S$ 的开头有 $a$ 个 0,结尾有 $b$ 个 0。将 $S$ 去掉开头和结尾的 0 所得01串记作 $T$。答案是 $(a+1)(b+1)f(T)$。

    以下假设 $S$ 以1开头且以1结尾,$S$ 的长度是 $n$。结果串也必然以1开头且以1结尾。
    用 $S[l,r]$ 表示 $S$ 的下标从 $l$ 到 $r$ 的子串。

    将最终结果分成若干类
    第一类,全是1。
    第二类,至少包含一个零。

    第二类又可以按照第一个0之前有几个1加以细分:
    10...1
    110...1
    1110...1
    ...

    只要解决10...1这一类,就可以解决其余的类,因为它们是子问题。
    我们按1后面紧跟着的0的个数分类。
    101...
    1001...
    ...
    假设 $S$ 的第一个1之后有2个0,即 $S$ 形如 1001...
    则 101...,1001... 这两类的数量都是 $f(S[4,n])$。
    现在要问,10001... 这类结果串有多少个?
    设 $S$ 中第一个其后紧跟着的0的数量大于等于3的1之后的那个1的下标是 $i$,则形如10001...的结果串有 $f(S[i,n])$ 个。

    于是想到:从右往左,对于 $S$ 的每个以 1 开头的后缀 $S[i,n]$ 计算 $f(S[i,n])$。维护一个数组 $g$,设最近一次遇到的在其之前至少有 $k$ 个0的那个1的下标是 $j$($dots 1underbrace{0dots 0}_{ ext{至少 $k$ 个 $0$}}color{red}{1}dots$,红色的 $1$ 的下标是 $j$),则 $g[k] = f(S[j..n])$,若满足条件的 $j$ 不存在,则 $g[k] = 0$。将数组 $g$ 的元素之和记作 $G$。每次遇到 $S_i = 1$,更新 $g$ 和 $G$,$f(S[i,n])$ 等于迄今在每个 1 处的 $G$ 之和再加上 $S[i,n]$ 内 1 的个数。

  • 相关阅读:
    博客开启
    .NET 异常
    .NET 深入研究
    算法研究
    数据库相关
    非比较排序算法———桶排序(箱子排序)
    非比较排序算法———计数排序
    NHibernate深入学习
    数据结构与算法
    结对编程1 四则运算生成器的改进(201421123060 61 40)
  • 原文地址:https://www.cnblogs.com/Patt/p/13394766.html
Copyright © 2011-2022 走看看