[NOIP2013 提高组] 积木大赛

题目描述

春春幼儿园举办了一年一度的“积木大赛”。今年比赛的内容是搭建一座宽度为 nn 的大厦,大厦可以看成由 nn 块宽度为 11 的积木组成,第 ii 块积木的最终高度需要是 h_ihi​。

在搭建开始之前,没有任何积木(可以看成 nn 块高度为 00 的积木)。接下来每次操作,小朋友们可以选择一段连续区间 [l, r][l,r],然后将第 LL 块到第 RR 块之间(含第 LL 块和第 RR 块)所有积木的高度分别增加 11。

小 M 是个聪明的小朋友,她很快想出了建造大厦的最佳策略,使得建造所需的操作次数最少。但她不是一个勤于动手的孩子,所以想请你帮忙实现这个策略,并求出最少的操作次数。

输入格式

包含两行,第一行包含一个整数 nn,表示大厦的宽度。

第二行包含 nn 个整数,第 ii 个整数为 h_ihi​。

输出格式

建造所需的最少操作数。

输入输出样例

输入 #1复制

5
2 3 4 1 2

输出 #1复制

5

说明/提示

【样例解释】

其中一种可行的最佳方案,依次选择:[1,5][1,5],[1,3][1,3],[2,3][2,3],[3,3][3,3],[5,5][5,5]。

【数据范围】

  • 对于 30\%30% 的数据,有 1 \leq n \leq 101≤n≤10;
  • 对于 70\%70% 的数据,有 1 \leq n \leq 10001≤n≤1000;
  • 对于 100\%100% 的数据,有 1 \leq n \leq 1000001≤n≤100000,0 \leq h_i \leq 100000≤hi​≤10000。

一般区间操作首先要想差分————yql

差分是个啥?

△f=f(x+1)-f(x),就像微积分,但把增量换成了1,也叫有限微积分

这里定义差分f[i]=h[i]-h[i-1],i=1...n+1,h[0]=0,h[n+1]=0.

容易知道f中正值之和等于负值之和的绝对值

Σf[i]=Σh[i]-h[i-1]=h[n+1]-h[0]=0,得证.

于是我们可以猜ans=正值之和

证明?

如果f[i]为正,容易知道我们要往这一摞上搭积木,所以ans+=h[i]-h[i-1]=f[i]

如果f[i]为负,可以在之前搭的时候一起搭上去,所以ans不变

当然这可以通过其他方式省去数组,但差分有更多的用途

考虑区间加

在a(原数组,下同)上表现为i=l...r,a[i]+=w;

而在f数组上的表现则为f[l]+=w,f[r+1]-=w.

证明自己yy一下就好,很容易

于是这东西可以O(1)修改

可以推广到二维和树上,区间乘法应该也可以???适用于多询问少修改的题

然后今天有一道毒瘤题要求区间翻转+区间加+带负值积木大赛+查询历史版本

于是可以差分做


考虑翻转之后的f

对于l+1~r+1,可以取反然后翻转

对于l和r,暴力处理一下即可

丢到平衡树上就好了

历史版本加上一个操作树就好

没有强制在线就不需要持久化


到这是yql原话反正我没怎么听懂orz

最后回到这个题上来233

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int c[110000],n,ans=0;
inline int getin()
{
	int x=0;char ch=getchar();
	while(ch<'0'||ch>'9')ch=getchar();
	while(ch>='0'&&ch<='9')x=x*10+ch-48,ch=getchar();
	return x;
}
inline int max(int a,int b)
{
	if(a>b)return a;return b;
}
int main()
{
	n=getin();
	for(register int i=1;i<=n;i++)
		c[i+1]=-getin(),c[i]-=c[i+1],ans+=max(c[i],0);
	printf("%d",ans);
}

4ms...慢的要死,可以自己再卡卡常数

区间的话分块O(nsqrt(n))/线段树(nlogn)啥的都能做

我这么菜不会别的233

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
noip2013普及初赛是全国信息学奥林匹克联赛的一场选拔赛。该比赛旨在选拔初学者,对编程和算法有一定基础的学生,通过比赛形式来考察他们的知识水平和解题能力。 比赛题目通常会涉及各个领域的算法和数据结构,如图论、动态规划、数论等。题目难度逐步增加,从简单的输出结果,到复杂的程序设计与代码实现,考察选手的逻辑思维和编程能力。 参赛选手需要通过自己的思考和编程实现来解决题目,同时时间也是一个重要因素。比赛中,选手需要在规定的时间内独立完成所有题目,对于复杂的题目需要迅速想出解题思路并进行编码。因此,在比赛中,选手的临场发挥和解题速度也是需要考虑的因素。 noip2013普及初赛的结果将作为选拔阶段的一个重要依据,选出表现出色的选手进入到更高阶段的比赛,对于他们来说,这是一次展示自己实力的机会。 此外,noip2013普及初赛,也给了参赛选手一个交流的平台。选手们可以通过比赛结交同好,相互切磋,共同进步。同时,比赛结束后,还有详细的解题分析和讲解,有助于参赛选手对自己在比赛中的不足进行反思与改进。 总之,noip2013普及初赛是一个考察学生编程和算法能力的选拔赛,通过比赛的形式来选拔出优秀的选手。这对于参赛选手来说,是一次展示自己才华的机会,也是一个展示自己实力和提高自己能力的平台。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值