【题目描述】

给你一个 \(01\) 序列,你可以进行如下操作若干次(或零次):

  • 将序列中形如 \(101\cdots01\) 的一个子串(即 \(1(01)^k\),\(k\ge 1\))替换成等长的 \(010\cdots10\)(即 \(0(10)^k\))。

你要操作使得 \(1\) 的个数尽可能少,输出最少的 \(1\) 的个数。

【思路】

一开始看到这道题不会做,问老师,于是:

于是开始自己造数据,把结论玩出来了。

首先考虑这样子的情况:A00B,\(A,B\) 是一个 \(01\) 序列。我们不难发现,对于这种情况,\(A,B\) 不管怎么替换,都不可能将 \(A,B\) 连在一起。于是我们有了第一步,将整个串分割开,分割条件是出现两个及以上连续的 \(0\)。

现在我们得到了一大堆 \(01\) 序列,这些序列都没有两个及以上连续的 \(0\)。对于每一个序列,可以分为两种情况:

  • \(111\cdots111\):对于全部都是 \(1\) 的串,我们无法对其进行操作,答案加上区间长度。
  • \(111\cdots101\cdots111\):对于其中至少有一个 \(0\) 的串,我们一定有一种方法让他只剩下一个 \(1\),答案加 \(1\)。证明过程放在最后。

于是这道题就做完了。

嗯。

【Code】

#include <bits/stdc++.h>
using namespace std; char s[1000005];
int n,ans; //判断是否是区间开始
bool Is_start(int x){
if(x==1&&s[x]=='1') return true;
if(x==2&&s[x-1]=='0'&&s[x]=='1') return true;
if(x>=3&&s[x-2]=='0'&&s[x-1]=='0'&&s[x]=='1') return true;
return false;
} //判断是否为区间结束
bool Is_end(int x){
if(s[x]=='1'&&s[x+1]=='0'&&s[x+2]=='0') return true;
return false;
} //判断一个区间中是否有 0
bool No_zero(int l,int r){
for(int i=l;i<=r;i++){
if(s[i]=='0') return false;
}return true;
} int main()
{
scanf("%s",s+1);
n=strlen(s+1);
s[n+1]=s[n+2]='0';
int l=0,r=0;
for(int i=1;i<=n;i++){
if(Is_start(i)) l=i; //是区间开始
if(Is_end(i)){ //是区间结束
r=i;
if(No_zero(l,r)) ans+=r-l+1; //全部是 1,无法消去
else ans+=1; //其中有 0,消到一个
}
}
printf("%d",ans);
return 0;
}

【证明】

证明内容:一个至少包含一个 \(0\) 的 \(01\) 串,最后一定可以被消除到只剩一个 \(1\)

我们从这个 \(01\) 串最右边的那个 \(0\) 开始。

那么这个串可以表示为 \(1\cdots1110111 \cdots 1A\) 的形式,\(A\) 是一个 \(01\) 串。

\(\begin{array}{c}
\ \ \ \ \ \ \ \ {\color{Blue}1} \cdots {\color{Blue}1}{\color{Blue}1}{\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Blue}1}{\color{Blue}1} \cdots {\color{Blue}1}A \\
\Longrightarrow {\color{Blue}1} \cdots {\color{Blue}1}{\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Blue}1} \cdots {\color{Blue}1}A \\
\Longrightarrow {\color{Blue}1} \cdots {\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Red}0}{\color{Blue}1} \cdots {\color{Blue}1}A \\
\Longrightarrow {\color{Blue}1} \cdots {\color{Red}0}{\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Red}0} \cdots {\color{Blue}1}A
\end{array}\)

在替换的这个串的左边会碰到这个串的边缘:

\(\begin{array}{c}
\ \ \ \ \ \ \ \ {\color{Blue}1}{\color{Blue}1}{\color{Blue}1}{\color{Blue}1}{\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Red}0} \cdots A \\
\Longrightarrow {\color{Blue}1}{\color{Blue}1}{\color{Blue}1}{\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Red}0}{\color{Blue}1} \cdots A \\
\Longrightarrow {\color{Blue}1}{\color{Blue}1}{\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Red}0} \cdots A \\
\Longrightarrow {\color{Blue}1}{\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Red}0}{\color{Blue}1} \cdots A \\
\Longrightarrow {\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Red}0} \cdots A \\
\Longrightarrow {\color{Red}0}{\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Red}0}{\color{Blue}1} \cdots A \\
\Longrightarrow {\color{Red}0}{\color{Red}0}{\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Red}0} \cdots A \\
\Longrightarrow {\color{Red}0}{\color{Red}0}{\color{Red}0}{\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Red}0}{\color{Blue}1} \cdots A \\
\Longrightarrow {\color{Red}0}{\color{Red}0}{\color{Red}0}{\color{Red}0}{\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Red}0} \cdots A \\
\Longrightarrow {\color{Red}0}{\color{Red}0}{\color{Red}0}{\color{Red}0}{\color{Red}0}{\color{Blue}1}{\color{Red}0}{\color{Blue}1} \cdots A \\
\end{array}\)

然后慢慢缩回来。

而它的右边则有两种情况:

  • 碰到 \(1\),一起改变掉。

  • 碰到 \(0\):

    \(\begin{array}{c}
    \ \ \ \ \ \ \ \ {\color{Red}0}{\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Blue}1}{\color{Blue}1}{\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Blue}1}{\color{Blue}1}{\color{Blue}1} \cdots A \\
    \Longrightarrow {\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Blue}1}{\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Blue}1}{\color{Blue}1}{\color{Blue}1} \cdots A \\
    \Longrightarrow {\color{Red}0}{\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Blue}1}{\color{Blue}1}{\color{Blue}1} \cdots A \\
    \Longrightarrow {\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Blue}1}{\color{Blue}1}{\color{Blue}1} \cdots A \\
    \Longrightarrow {\color{Red}0}{\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Blue}1}{\color{Blue}1} \cdots A \\
    \Longrightarrow {\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Blue}1} \cdots A \\
    \Longrightarrow {\color{Red}0}{\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Red}0}{\color{Blue}1}{\color{Red}0}{\color{Blue}1} \cdots A \\
    \end{array}\)

P10160 [DTCPC 2024] Ultra 题解的更多相关文章

  1. JLOI2016 简要题解

    「JLOI2016」侦查守卫 题意 有一个 \(n\) 个点的树,有 \(m\) 个关键点需要被监视.可以在其中一些点上插眼,在 \(i\) 号点上放眼需要花费 \(w_i\) 的代价,可以监视距离 ...

  2. [Luogu 2024] 食物链

    [Luogu 2024] 食物链 几句随感 我依稀记得联赛前本来想做这题的时候. 当年啊弱到题目与标签就令我望而生畏. 还有翻阅很多遍那现在已经被遗弃的博客. 看到题解中「三倍数组」的字眼就怕难而放弃 ...

  3. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  4. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  5. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  6. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  7. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  8. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  9. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  10. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

随机推荐

  1. 5分钟上手Python爬虫:从干饭开始,轻松掌握技巧

    很多人都听说过爬虫,我也不例外.曾看到别人编写的爬虫代码,虽然没有深入研究,但感觉非常强大.因此,今天我决定从零开始,花费仅5分钟学习入门爬虫技术,以后只需轻轻一爬就能查看所有感兴趣的网站内容.广告? ...

  2. Linux查看用户的7个命令

    Linux是中国IT实验室的一个技术频道.包含桌面应用,Linux系统管理,内核研究,嵌入式系统和开源等一些基本分类      在Linux系统里,我们会经常用Linux查看用户的命令,在这里我们一些 ...

  3. Django 使用 Nginx + uWSGI 启动

    一.前言 购买了腾讯云服务器练习 Django 项目时, # 最开始用的启动 Django 项目命令 python3 manage.py runserver 0.0.0.0:80 后面发现我一旦把 x ...

  4. 【UE插件DTRabbitMQ】 虚幻引擎蓝图连接RabbitMQ服务器使用插件说明

    本插件可以使用蓝图连接 RabbitMQ服务器,并推送或者监听消息. 下载地址地址在文章最后. 1. 节点说明 Create RabbitMQ Client - 创建RabbitMQ客户端对象 创建一 ...

  5. Java split 分割字符串避坑

    使用split进行字符串分割时需要注意2点 1.特殊字符作为分隔符时需要使用\\进行转义(如\\ -> \\\\; | -> \\| ) 特殊字符 .$|()[{^?*+\\ 例如对&qu ...

  6. 工具推荐--DRAWIO流程图软件

    简介 DRAWIO是一款开源的流程图软件,可以快速绘制各种流程图,支持图形导入和图像插入,且可以类似excel一样分页,能够以最简介的方式实现最复杂的功能; 基础功能 作为一款流程图软件,绘制流程图的 ...

  7. KingbaseES V8R6 集群运维案例 -- 集群备份到nfs共享存储初始化错误

    案例说明: 在主备库建立nfs共享存储的文件系统,作为sys_rman备份的repo-path,在备库作为repo-path节点执行备份,出现数据库连接到'5432端口的错误',数据库实际的服务端口为 ...

  8. KingbaseES V8R6集群备份恢复案例之---备份初始化“can not find primary node”故障

    案例说明: KingbaseES V8R6集群,备库作为repo-path节点,建立类型为'cluster'模式的备份,在执行sys_backup.sh init时,出现"can not f ...

  9. 误删除系统超级用户(superuser)权限的恢复方式

    在使用KingbaseES数据库的时候,系统默认存在一个跟系统初始化用户同名的Superuser(默认是system用户,可更改). 这个Superuser的存在其实对于权限的管控是很有用的,但是如果 ...

  10. [apue] 作为 daemon 启动, Unix Domain Socket 侦听失败?

    前段时间写一个传递文件句柄的小 demo,有 server 端.有 client 端,之间通过 Unix Domain Socket 通讯. 在普通模式下,双方可以正常建立连接,当server端作为d ...