[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];
}

最新文章

  1. Windows下Nginx Virtual Host多站点配置详解
  2. jquery placeholder
  3. Lex&amp;Yacc Parser错误发生后再次parser之前恢复初始状态
  4. Activiti 学习笔记(2016-8-30)
  5. struts2类型转换器、 类型转换错误 以及INPUT view
  6. Games:取石子游戏(POJ 1067)
  7. Java中this与super的区别【6】
  8. Installation failed with message INSTALL_FAILED_UID_CHANGED.--APK安装失败解决方法
  9. linux设备驱动归纳总结(九):1.platform总线的设备和驱动【转】
  10. java中的快捷键
  11. 采购IC应该知道的十大网站
  12. IOS --- 日期时间格式 更改
  13. sqlserver生成随机数 2011-12-21 15:47 QQ空间
  14. HDB3编码器
  15. docker常用命令记录
  16. iOSOpenDev安装使用
  17. 雇佣K个工人的最小费用 Minimum Cost to Hire K Workers
  18. JAVA的初始化顺序:
  19. python的list()列表数据类型的方法详解
  20. 【C#】C#委托学习

热门文章

  1. Java中,一个存在了十几年的bug...
  2. Java基础之六、Java编程思想(8-10)
  3. OpenLayers 6 学习笔记2 WMS服务避坑记录
  4. Android中通过数组资源文件xml与适配器两种方式给ListView列表视图设置数据源
  5. Android中点击按钮获取星级评分条的评分
  6. navicat连接异常 authentication plugin &#39;caching_sha2_password&#39; 问题解决
  7. clr via c# 泛型
  8. mysql必知必会--过 滤 数 据
  9. 图片-定义select向下箭头样式
  10. c++ 浮点数小数位