可以将问题用形象的方式来表述。给定一排点,第 \(i\) 个点有它需要的覆盖次数 \(a_i\)。有两种线段,一种能覆盖连续的一些点,称其为连续线段;另一种能覆盖相邻间隔为 \(1\) 的一些点,称其为为间隔线段。现在要用尽可能少的线段覆盖每个点 \(i\) 恰好 \(a_i\) 次。

发现如果没有间隔线段就是被某组织出烂的原题。显然,每次取最长的非 \(0\) 段最优。

回到本题,来证明一个结论:假设 \(a_1\sim a_i>0\),\(a_{i+1}=0\) 且 \(i>1\),选一条从 \(1\sim i\) 的连续线段一定不劣。

将 \(1\sim i\) 分成奇数偶数两组,那么每组都可以用间隔线段完全覆盖且不会影响到另一组,这意味着如果不用连续线段两者可以用上面的方法单独计算

反之如果我们选择了一条 \(1\sim i\) 的连续线段,两组均会被完全覆盖,代价减少了 \(1\),看起来会更优

但现在点 \(i\) 所在的组可能对后面产生贡献(覆盖到点 \(i+2\)),而另一组不行。所以我们可以以点 \(i+2\) 为开头选一条间隔线段,加上 \(1\sim i\) 的连续线段,代价为 \(2\),不劣于选两条间隔线段。

接着怎么做呢?唯一需要考虑的就是前面有线段连过来。在处理点 \(i\) 时,记连过来的连续线段数量为 \(x\),能覆盖到点 \(i\) 的间隔线段数量为 \(y\),不能覆盖到点 \(i\) 的间隔线段数量为 \(z\)。

首先处理一下特殊情况:连过来的线段太多了,即 \(x+y>a_i\),有 \(k\gets x+y-a_i\) 条线段不能向后继续连。但我们会发现留下间隔线段还是连续线段是由后面的点决定的,所以不妨将 \(x\gets x-k\),\(y\gets y-k\),反悔标记置为 \(k\),表示可以免费连向下一个点的线段个数(线段的种类可以任意选)。但是这样会出现一种情况,\(x<k\) 或 \(y<k\),此时的反悔可能是不合法的。对于这种情况,我们将少的一种线段置为 \(0\),另一种线段对应减少,即可保证合法。

然后就好办了,根据之前的结论,处理 \(a_{i-1}\) 与 \(a_i\)。能用连续线段就用,如果 \(i-1\) 还有剩下就用间隔线段。

当然还有一些需要注意的细节。

  • 如果更新了标记,最后需要将 \(a_i\) 置为 \(k\),答案减去 \(k\),同时清空标记。
  • 尽量从 \(i=2\) 开始做,防止出现一些边界问题。
  • 最后多做一次,计算 \(n\) 位置的答案。

时间复杂度 \(O\left(n\right)\)。

code:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define Min(x,y)((x)<(y)?x:y)
int read()
{
int A;
bool K;
char C;
C=A=K=0;
while(C<'0'||C>'9')K|=C=='-',C=getchar();
while(C>'/'&&C<':')A=(A<<3)+(A<<1)+(C^48),C=getchar();
return(K?-A:A);
}
int main()
{
int t,n;
ll last,now,k,x,y,z,tag,ans,tmp;
t=read();
while(t--)
{
n=read(),last=read();
ans=tag=x=y=z=0;
while(n--)
{
now=(n?read():0);
if(now<x+y)
//处理多余的线段
{
k=x+y-now;
//必须要结尾的线段
if(x<k)y-=k-x,k=x;
if(y<k)x-=k-y,k=y;
x-=k;
y-=k;
now-=k;
tag=k;
//向后所能免费延伸的线段
}
now-=x+y;
//新的必须经过当前点的线段
tmp=Min(last,now);
ans+=tmp;
last-=tmp;
now-=tmp;
x+=tmp;
//用连续线段覆盖
ans+=last;
z+=last;
//用间隔线段覆盖
last=now|tag;
ans-=tag;
tag=0;
//处理标记
swap(y,z);
//奇偶互换
}
cout<<ans<<endl;
}
return 0;
}

P6631 [ZJOI2020] 序列的更多相关文章

  1. Solution -「ZJOI 2020」「洛谷 P6631」序列

    \(\mathcal{Description}\)   Link.   给定一个长为 \(n\) 的非负整数序列 \(\lang a_n\rang\),你可以进行如下操作: 取 \([l,r]\),将 ...

  2. 【夯实PHP基础】UML序列图总结

    原文地址 序列图主要用于展示对象之间交互的顺序. 序列图将交互关系表示为一个二维图.纵向是时间轴,时间沿竖线向下延伸.横向轴代表了在协作中各独立对象的类元角色.类元角色用生命线表示.当对象存在时,角色 ...

  3. Windows10-UWP中设备序列显示不同XAML的三种方式[3]

    阅读目录: 概述 DeviceFamily-Type文件夹 DeviceFamily-Type扩展 InitializeComponent重载 结论 概述 Windows10-UWP(Universa ...

  4. 软件工程里的UML序列图的概念和总结

    俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习! 软件工程的一般开发过程:愿景分析.业务建模,需求分析,健壮性设计,关键设计,最终设计,实现…… 时序图也叫序列图(交互图),属于软件 ...

  5. python序列,字典备忘

    初识python备忘: 序列:列表,字符串,元组len(d),d[id],del d[id],data in d函数:cmp(x,y),len(seq),list(seq)根据字符串创建列表,max( ...

  6. BZOJ 1251: 序列终结者 [splay]

    1251: 序列终结者 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 3778  Solved: 1583[Submit][Status][Discu ...

  7. 最长不下降序列nlogn算法

    显然n方算法在比赛中是没有什么用的(不会这么容易就过的),所以nlogn的算法尤为重要. 分析: 开2个数组,一个a记原数,f[k]表示长度为f的不下降子序列末尾元素的最小值,tot表示当前已知的最长 ...

  8. [LeetCode] Sequence Reconstruction 序列重建

    Check whether the original sequence org can be uniquely reconstructed from the sequences in seqs. Th ...

  9. [LeetCode] Binary Tree Longest Consecutive Sequence 二叉树最长连续序列

    Given a binary tree, find the length of the longest consecutive sequence path. The path refers to an ...

随机推荐

  1. C. Vladik and Memorable Trip 解析(思維、DP)

    Codeforce 811 C. Vladik and Memorable Trip 解析(思維.DP) 今天我們來看看CF811C 題目連結 題目 給你一個數列,一個區段的數列的值是區段內所有相異數 ...

  2. Linux配置和管理设备映射多路径multipath

    (一)多路径管理软件的由来 在企业中,服务器与存储通常是分开放置的,服务器上的硬盘通常用来安装操作系统和应用软件,业务数据则是存储在单独的存储设备上,那么,服务器与存储是如何连接的呢?根据存储协议,经 ...

  3. 我的第三次C语言作业

    我的第三次C语言作业 这个作业属于哪个课程 https://edu.cnblogs.com/campus/zswxy/SE2020-2 这个作业要求在哪里 https://edu.cnblogs.co ...

  4. 转:Microsoft Dynamics AX内部版本号概述

    Overview of Microsoft Dynamics AX build numbers 转自:https://community.dynamics.com/ax/b/axsupport/arc ...

  5. 配置交换机Trunk接口流量本地优先转发(集群/堆叠)

    组网图形 Eth-Trunk接口流量本地优先转发简介 在设备集群/堆叠情况下,为了保证流量的可靠传输,流量的出接口设置为Eth-Trunk接口.那么Eth-Trunk接口中必定存在跨框成员口.当集群/ ...

  6. phpword读取内容和样式 生成新的内容

    table样式还未读出 正在测试中, 目前有 rows cell textrun等样式 顺序不固定 可以设定 <?php require 'vendor/autoload.php'; use P ...

  7. 依赖注入DI(IOC)容器快速入门

    1.什么是IOC IOC是一种设计模式,全程控制翻转或叫依赖注入.更详细介绍见http://martinfowler.com/articles/injection.html 2.为什么用IOC 我们通 ...

  8. BIM+GIS它们各有什么优缺点

    BIM+GIS它们各有什么优缺点?应用有哪些优势?BIM模型精细程度高,语义信息丰富,侧重整合和管理建筑物自身所有阶段信息,包括建筑物所有微观图形化和非图形化信息,三维GIS侧重宏观.大范围地理环境与 ...

  9. mysql 面试100 问(精华学习)。待开始理

    https://juejin.im/post/6850037271233331208 https://juejin.im/entry/6844903681091977229

  10. IO复用之poll

    主要用一个例程来讲解poll,包含客户端和服务器端. poll函数没有FD_SETSIZE的限制 int poll(struct pollfd * fdarray, unsigned long nfd ...