备注

发表时间:2023-06-17 21:51

前言

yny 学长来 cdqz 讲课,写一篇讲课的题的题解纪念一下。

题意

给你一个 01 序列,有以下操作:

  • 选择一段区间

    设 \(cnt_0,cnt_1\) 分别表示该区间中 01 的数量。

    花费 \(|cnt_0-cnt_1|+1\) 的代价对区间进行升序排序。

求最小代价。

思路

肯定是使每次操作的区间中 01 个数差越小越好,所以考虑每次都选择尽可能长01 个数差最小的区间。

如果最前面一段都是 0,那就不用管前面。相当于每次都从第一个 1 开始考虑(注意不是操作区间的左端点)。

题解

因为每次操作必须是 \(cnt_0 = cnt_1\) 才最优。

所以现在考虑如何找最优区间。

为了简化思维,我们可以先只考虑整个序列 01 多时如何求解,因为这样我们可以加 0 进行贪心。

弱化版

首先每次从区间最左端的 1 开始考虑,我们可以贪心去找最优区间。

因为 0 永远比 1 多,所以如果后面的 0 少了可以直接从前面拿 0 来补齐。

所以现在问题就在如何求最优区间。

此时,本题最妙的点来了。我们可以给 01 赋值为 \(1\) 和 \(- 1\),将这个区间的变化用图表示。

我们假设要找序列 \(S_l\) 的最优区间右端点 \(S_r\),就可以在图中做一条与横轴平行的直线。

其中曲线与直线最右端的交点就是 \(S_r\)。

而图中的曲线就只用记录与直线 \(y = i \left \{i \in [1,n] \mid i \in Z^+\right \}\) 的最右端交点。

最后,如何将方法一般化呢?

我们可以将原来 01 多的序列变成上面这种特殊序列。

因为原序列中 1 要移到后面、0 要移到前面,所以其实我们只用将原序列翻转,再给 0 1 都取反就行了(读者可自行思考)。

注意

  • 特判序列是否已为升序。

  • 01 赋值。

代码

/*
* @Author: H.F.Y
* @Date: 2023-06-17 16:40:55
* @Last Modified by: H.F.Y
* @Last Modified time: 2023-06-17 17:41:39
*/
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 2e5 + 5;
int n, a[N], pre_max[N];
char c[N];
signed main(){
//freopen(,stdin);
//freopen(,stdout);
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
cin >> T;
while(T--){
cin >> n; int cnt1 = 0, cnt0 = 0;
memset(pre_max, 0, sizeof pre_max);
memset(a, 0, sizeof a);
for(int i = 1; i <= n; ++i){
cin >> c[i]; a[i] = ((c[i] - '0') ? 1 : - 1);
if(a[i] == 1)++cnt1;
else ++cnt0;
}
bool opt = true;
for(int i = n - 1; i; --i)if(a[i] > a[i + 1])opt = false;
if(opt){
cout << 0 << '\n';
continue;
}
if(cnt1 == cnt0){
cout << 1 << '\n';
continue;
}
else if(cnt1 > cnt0){
swap(cnt1, cnt0);
for(int i = 1; i <= n; ++i)a[i] = ((c[n - i + 1] - '0') ? - 1 : 1);
}
for(int i = 1, sum = 0; i <= n; ++i){
sum -= a[i];
if(~ sum)pre_max[sum] = i;
}
int ans = 1, i = 0, cnt = cnt0 - cnt1;
while(a[i + 1] == - 1 and i < n)++i;
while(i < cnt){
++ans;
int t = pre_max[i] - i + 1; t /= 2;
i += t;
}
cout << ans << '\n';
}
return 0;
}

CF1693F题解的更多相关文章

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

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

  2. noip2016十连测题解

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

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

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

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

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

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

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

  6. 2016ACM青岛区域赛题解

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

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

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

  8. 网络流n题 题解

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

  9. CF100965C题解..

    求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...

  10. JSOI2016R3 瞎BB题解

    题意请看absi大爷的blog http://absi2011.is-programmer.com/posts/200920.html http://absi2011.is-programmer.co ...

随机推荐

  1. Flutter枚举

    Flutter枚举 Enum Extension 在Dart2.7版本,Dart新增了扩展函数,使枚举相关的代码定义.调用更加简洁 通过扩展枚举定义方法 定义一个元素枚举 enum Element { ...

  2. 开启Word、Excel、PPT时速度很慢的一种解决方法

      本文介绍基于修改加载项,解决Microsoft Office系列软件开启速度较慢的办法.   最近,发现Excel软件的打开速度越来越慢,会在一定程度上影响工作效率.因此尝试对此加以解决.其中,本 ...

  3. 2024年1月Java项目开发指南9:密码加密存储

    提前声明: 你不会写这加密算法没关系啊,你会用就行. 要求就是:你可以不会写这个加密算法,但是你要知道加密流程,你要会用. @Service public class PasswordEncrypto ...

  4. 【Python】【爬虫】【爬狼】003_获取搜索结果的页数

    # 获取搜索内容的页数 需要的包 import urllib.request # 获取网页源码 import re # 正则表达式,进行文字匹配 from bs4 import BeautifulSo ...

  5. 【前端】【H5 API】地理定位(获取经纬度)

    H5 API 地理定位 地理定位在日常生活中应用比较广泛,例如,互联网打车.在线地图等.在HTML 5的规范中,增加了获取用户地理位置信息的接口Geolocation,开发者可以通过经纬度来获取用户的 ...

  6. 龙哥量化:通达信板块概念FAQ,*期强势、*期弱势是怎么划分的?等问题是官网的解释,股友可以根据文章的提示迸发策略灵感

    如果您需要代写公式, 请联系我. 龙哥QQ:591438821 龙哥微信:Long622889 比如第9条,*期强势:20日涨幅>=30%,     3日涨幅>0,非停牌.非ST.非未开板 ...

  7. Qt/C++地图动态绘制折线多边形矩形圆形标注点/可编辑拖动调整大小和位置

    一.前言说明 无论哪一家的地图,都提供了调用函数绘制各种覆盖物,但是有时候的场景是希望进入添加覆盖物模式,然后每次在地图上按下都自动生成对应的覆盖物比如圆形,这样就不需要用户提前知道经纬度坐标等参数, ...

  8. 关于Qt国产化系统开发的几点总结

    随着国产化的兴起,各种国产系统和国产数据库等逐渐进入开发者的世界,科普几个要点. 中标麒麟neokylin基于fedora. 银河麒麟kylin早期版本比如V2基于freebsd,新版本V4.V10基 ...

  9. Qt编写地图综合应用35-设备分布图

    一.前言 设备分布图在所有的地图应用案例项目中,最常见最普遍最基础,就是将项目中的设备信息,比如设备名称.设备所在的经纬度坐标.设备的其他信息(设备地址.设备参数等),通过标注点的形式添加到地图中,至 ...

  10. Qt编写安防视频监控系统40-onvif线程处理

    一.前言 整个onvif模块大部分的功能都有了以后,除了在demo上点点按钮可以执行获取结果显示外,最终还是要应用到视频监控中,在按钮上点点和系统中后台自动运行是两码事,比如onvif校时和事件订阅, ...