zoukankan      html  css  js  c++  java
  • [AtCoder Code Festival 2017 QualB D/At3575] 101 to 010

    [Atcoder Code Festival 2017 QualB/At3575] 101 to 010

    有一个01序列,每次可以选出一个101,使其变成010,问最优策略下能操作几次?

    考虑像 1111101 或者 1011111 这样的东西,它们最多能被操作的次数为长度-2

    (l[i]) 表示 (i) 左边第一个 (0) 的位置

    (f[i]) 表示前缀的最大操作数

    对于每个 (a[i]=1) 的位置,我们考虑进行转移

    • 对于 ([i-2,i]) 为 101 的情况,

      • 对类似100 | 1111101这种,我们得到

      [f[i] leftarrow f[l[i-2]] + i-l[i-2]-2 ]

      • 对于类似 11101| 11101 这种,我们得到

      [f[i] leftarrow f[l[i-2]+1] +i-(l[i-2]+1)-2 ]

    • 否则,考虑类似 1011111 这样的情况,这时 (l[i]>1, a[l[i]-1]=1),我们得到

      [f[i] leftarrow f[l[i]-2] +i-l[i]+2-2 ]

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 1000005;
    
    char s[N];
    int n,l[N],f[N];
    int main() {
        scanf("%d%s",&n,s+1);
        for(int i=1;i<=n;i++) {
            if(s[i]=='0') l[i]=i;
            else l[i]=l[i-1];
        }
        for(int i=1;i<=n;i++) {
            f[i]=f[i-1];
            if(s[i]=='1') {
                if(s[i-2]=='1' && s[i-1]=='0')
                    f[i]=max(f[i],max(f[l[i-2]]+i-l[i-2]-2,f[l[i-2]+1]+i-l[i-2]-3));
                else if(l[i]>1 && s[l[i]-1]=='1') f[i]=max(f[i],f[l[i]-2]+i-l[i]);
            }
        }
        cout<<f[n];
    }
    
  • 相关阅读:
    as3 三行三列 布满9个为一个界面
    as3 判断鼠标移动方向
    求两点之间 的直线距离
    AS3 localToGlobal、globalToLocal方法的总结
    as3 TweenMax TweenLite方法
    禁止点击
    影片 发光 变色
    ASCII字符串互换
    关于C语言的书
    关于态度
  • 原文地址:https://www.cnblogs.com/mollnn/p/12270871.html
Copyright © 2011-2022 走看看