ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

差分数组巧应用——507. 积木大赛

2021-02-14 20:33:21  阅读:242  来源: 互联网

标签:积木 bi 差分 最少 操作 507 正数


春春幼儿园举办了一年一度的“积木大赛”。

今年比赛的内容是搭建一座宽度为n的大厦,大厦可以看成由n块宽度为1的积木组成,第i块积木的最终高度需要是hiℎi。

在搭建开始之前,没有任何积木(可以看成块高度为 0 的积木)。

接下来每次操作,小朋友们可以选择一段连续区间[L,R],然后将第L块到第R块之间(含第 L 块和第 R 块)所有积木的高度分别增加1。

小M是个聪明的小朋友,她很快想出了建造大厦的最佳策略,使得建造所需的操作次数最少。

但她不是一个勤于动手的孩子,所以想请你帮忙实现这个策略,并求出最少的操作次数。

输入格式

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

第二行包含n个整数,第i个整数为hiℎi。

输出格式

仅一行,即建造所需的最少操作数。

数据范围

1≤n≤1051≤n≤105,
0≤hi≤100000≤hi≤10000

输入样例:

5
2 3 4 1 2

输出样例:

5
难度:中等
时/空限制:1s / 128MB
总通过数:267
总尝试数:369
来源:NOIP2013提高组
算法标签

算法

(差分,贪心) O(n)
我们逆向思考:假设给定了每块积木的高度,每次可以将某一段区间中的所有高度减一,问最少操作多少次可以将所有高度变成0。

原序列是: h1,h2,h3,…,hn 其中 hi≥1。

构造差分序列:

b1=h1

b2=h2−h1

b3=h3−h2

bn=hn−hn−1

bn+1=−hn

则将 hL,hL+1,…,hRhL,hL+1,…,hR 中的每个数减1的操作,等价于将 bL 减1, 将 bR+1 加1。关于差分算法可以参考 AcWing 797.。

因此问题变成每次从 b1,b2,…,bn+1中挑两个数,前一个减1,后一个加1,问最少操作多少次可以将所有数变成0。

首先,对于每个正数 bi>0,最少需要操作 bi 次,因此总操作次数一定不少于差分数组中所有正数之和 B。

然后我们构造一种操作方式,使得恰好可以通过 B 次操作,将所有数变成0。 那么就可以说明最少操作次数一定是所有正数之和。

操作方式如下:

从后往前操作,如果当前的 bi>0,则将其减1,并将其后的某个负数加1。
由于 ∑bi=0,因此从数量上看,正数和负数是一一对应的。
然后我们考虑在操作过程中,对于每个正数 bi,其后是否一定存在负数与之对应。由于差分数组的所有后缀 ∑n+1i=kbi=−hk≤0,因此在所有后缀中,正数之和一定小于等于负数之和,所以负数总是可以被找到的。

因此,上面的操作方式是合法的。

时间复杂度

求差分序列扫描一遍数组即可,因此总时间复杂度是 O(n)O(n)。

作者:yxc
链接:https://www.acwing.com/solution/content/3256/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

     
/*
因此问题变成每次从差分数组: b1,b2,…,bn+1b1,b2,…,bn+1 中挑两个数,
前一个减1,后一个加1,问最少操作多少次可以将所有数变成0。
首先,对于每个正数 bi>0,最少需要操作 bi 次,因此总操作次数一定不少于
差分数组中所有正数之和 B。然后我们构造一种操作方式,使得恰好可以通过 B 次操作,
将所有数变成0。 那么就可以说明最少操作次数一定是所有正数之和。
由于差分数组的所有后缀 ∑i=kn+1bi=-hk≤0,因此在所有后缀中,
正数之和一定小于等于负数之和,所以负数总是可以被找到的。
因此,上面的操作方式是合法的。
求差分序列扫描一遍数组即可,因此总时间复杂度是 O(n)。
*/
#include<iostream>
using namespace std;
int n,ans=0;
int a[100100];
int main(){
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=1;i<=n;i++) //差分数组的灵活应用 
		if(a[i]-a[i-1]>0) ans+=a[i]-a[i-1];
	cout<<ans<<endl;
	return 0;
}

  

标签:积木,bi,差分,最少,操作,507,正数
来源: https://www.cnblogs.com/ssfzmfy/p/14402598.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有