【基础练习】【贪心】【递推】NOIP2013提高组第五题 积木大赛题解

还是先把题目放上吧:

春春幼儿园举办了一年一度的“积木大赛”。今年比赛的内容是搭建一座宽度为n的大厦,大厦可以看成由n块宽度为1的积木组成,第n块积木的最终高度需要是hi。
在搭建开始之前,没有任何积木(可以看成n块高度为 0 的积木)。接下来每次操作,小朋友们可以选择一段连续区间[L,R],然后将第L块到第R块之间(含第 L 块和第 R 块)所有积木的高度分别增加1。
小M是个聪明的小朋友,她很快想出了建造大厦的最佳策略,使得建造所需的操作次数最少。但她不是一个勤于动手的孩子,所以想请你帮忙实现这个策略,并求出最少的操作次数。
输入格式
输入包含两行,第一行包含一个整数n,表示大厦的宽度。
第二行包含n个整数,第i个整数为hi。
输出格式
仅一行,即建造所需的最少操作数。
样例输入

5

2 3 4 1 2

样例输出


样例解释
其中一种可行的最佳方案,依次选择
[1,5] [1,3] [2,3] [3,3] [5,5]
数据范围
对于 30%的数据,有1 ≤ n ≤ 10;
对于 70%的数据,有1 ≤ n ≤ 1000;
对于 100%的数据,有1 ≤ n ≤ 100000,0 ≤ hi ≤ 10000。


解这道题目是听了vijos公开课上玉凤前辈提供的思路

题目意思如果画出图来是这样:


而我们要做的是对区间进行逐层搭建 换一种方式理解 就是对这个大厦的每一连续层进行逐层移除

首先想到的肯定是贪心 很朴素 每次去掉每个区间中最小的一个消去再统计即可

正如这张图:


这里不再赘述 还是说一下递归的简单做法吧

我们可以这样想 第一座楼房是两层,那么至少要移除两层,接下来是第二座楼房,由于它比第一座楼层高,第一座楼的两层移除时,它的下面两层也已经被移走了,只需要再移走最上面的一层,即与前一座楼的差值即可;第三座楼也是这样;而这时出现了第四座楼,它比第三座楼矮,这就是说,在移走前面的几层后,这个地方已经是空的了。第四座楼有一层,也就是说,第一层移走后,这里就是空白,将大厦分为两个区间(如第二张图,去除最下面黄色的一层)。因此,这座楼右面的区间和左边区间从第一层(也就是这座楼的层数)开始就不在一个系统,需要单独操作,相当于一座独立的大厦。所以我们在这时候将当前楼层更新成这座矮楼,之后的操作和之前一样。

简化成递推方程就是:

开始now=ans=第一座楼高度

从左往右扫描

如果 下一座楼高于now 则ans+=下一座楼和这座楼的高度差

否则 不作处理

更新now的值为下一座楼


放代码咯~

#include<cstdio>
using namespace std;

const int maxn=100000+10;
int a[maxn];

int main(){
	int n;
	scanf("%d",&n);
	for (int i=0;i<n;i++) scanf("%d",&a[i]);
	int now=a[0],ans=a[0];
	for(int i=1;i<n;i++){
		if (a[i]>now) ans+=(a[i]-now);
		now=a[i];
	}
	printf("%d",ans);
	return 0;
}

这道题目给我们的启发是,在我们想到一种解题策略的时候,再想想,说不定会有更好的方法。数形结合是关键。



——静女其姝,俟我於城隅。 爱而不见,搔首踟蹰。

  • 8
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: NOIP2008 普及复赛试是中国国家信息学奥林匹克选手选拔赛的试之一,比较经典且有一定难度。以下是对该试的解答。 本次试主要有三道目,分别是小数排列、整数取位和检测型括号序列。 小数排列这道要求给定一个正整数 n,求小于 n 的所有符合要求的小数的个数。解决这一的方法是利用排列合的知识,找出符合要求的小数的模式并计算其个数。具体的代码实现就需要对 n 进行拆分,计算个位数、十位数和百位数的可能情况并相乘即可得到结果。 整数取位这道要求给定一个整数 n 和一个非负整数 m,求 n 的第 m 个数字。解决这一的方法是将整数 n 转化为字符串,然后通过字符串的索引来获取第 m 个数字。 检测型括号序列这道要求判断给定的一个仅包含左右括号的字符串是否是合法的括号序列。解决这一的方法是使用栈的数据结构,遍历字符串,对于每个遇到的左括号,将其压入栈中;对于每个遇到的右括号,检查栈顶元素是否为对应的左括号,若是,则弹出栈顶元素,否则返回不合法。 以上就是对 NOIP2008 普及复赛试的简要解答,其中涉及到的算法和数据结构是编程中比较常见的基础知识,通过理解和掌握这些知识,可以帮助我们更好地解决类似的编程问。 ### 回答2: NOIP(全国青少年信息学奥林匹克竞赛)是中国举办的一项信息学竞赛活动。2008年,NOIP举办了普及复赛。以下是对该年度复赛试进行的解答。 复赛试一共有三大目,分别涉及到图的遍历、数学运算和字符串处理。 第一是关于图的遍历的。目给出一张有向图和一个起始节点,要求按照拓扑排序的原则遍历整个图,并输出遍历的结果。拓扑排序是一种将有向无环图的顶点进行排序的算法,具体实现可以使用DFS或者BFS。根据目给出的起始节点,我们可以使用DFS从该节点开始遍历图,并使用一个栈来存储遍历的结果。 第二是一个数学运算的目,要求计算一个给定数的乘方结果的各位数字之和。这可以通过将给定数转化为字符串,然后对字符串中的每位数字进行相加来解答。也可以将给定数分解为各位数字相加的形式。具体实现上可以使用循环或者递归的方式。 第三是一个关于字符串处理的任务,要求将输入字符串中的数字字符提取出来,并计算所有数字的平均值。这个问可以通过遍历字符串的方式来解决。对于每个字符,我们判断是否为数字字符,是的话就将其转换为数字并累加到一个总和上。最后将总和除以数字字符的个数,得到平均值。 总体来说,NOIP 2008 普及复赛试涵盖了图的遍历、数学运算和字符串处理的内容。通过解答这些问,可以增强对这些概念的理解,并提升解决实际问的能力。 ### 回答3: NOIP2008普及复赛试是一道考察动态规划和递归思想的目。目给出了一个整数n,要求计算出整数1到n的所有排列中,满足以下条件的排列的个数: 1.相邻两个数的差的绝对值不能等于1; 2.排列中的数不能重复。 首先,我们需要定义一个函数f(n),表示整数1到n的满足条件的排列的个数。我们可以将这个问转化为子问,即如何计算f(n-1)和f(n-2)等。 根据目要求,我们可以发现f(n)的值由两部分成:一部分是以n结尾的满足条件的排列的个数,另一部分是不以n结尾的满足条件的排列的个数。 对于第一部分,即以n结尾的排列,我们可以将其分为两种情况:n和n-2相邻,以及n和n-2不相邻。如果n和n-2相邻,那么有f(n-2)种情况。如果n和n-2不相邻,那么可以在以n-1结尾的排列后面加上n,所以有f(n-1)种情况。因此,以n结尾的满足条件的排列的个数为f(n) = f(n-1) + f(n-2)。 对于第二部分,即不以n结尾的排列,其个数就是f(n-1)。 所以,f(n) = f(n-1) + f(n-2) + f(n-1) = 2*f(n-1) + f(n-2)。 基本情况是当n=1时,满足条件的排列只有1个,即f(1)=1;当n=2时,满足条件的排列有2个,即f(2)=2。 通过递推,可以得到整个解空间中满足条件的排列的个数。 在编程实现时,可以使用动态规划来解决这道。先定义一个大小为n+1的数dp,dp[i]表示整数1到i的满足条件的排列的个数。然后,通过循环从3到n,依次计算dp[i]的值,最后返回dp[n]即可。 总结起来,这道是通过递推和动态规划的思想来计算满足条件的排列的个数。通过定义状态转移方程,将大问转化为小问,最后通过循环计算得出结果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值