P7399

[COCI2020-2021#5] Po

题目描述

有一个长度为 \(n\) 的数组。在初始状态下,所有元素都为 \(0\)

每次操作,可以将一个连续的区间 \([l,r]\) 内的所有数加上一个正整数 \(x\),但要求任意两个操作区间要么互不相交,要么一个包含另外一个。

请问能将原数组变为给定数组 \(a\) 的最少操作次数。

输入格式

第一行输入整数 \(n\)

第二行输入 \(n\) 个非负整数 \(a_i\)

输出格式

输出所需最少操作次数。

样例 #1

样例输入 #1

3
2 2 2

样例输出 #1

1

样例 #2

样例输入 #2

5
2 3 3 3 2

样例输出 #2

2

样例 #3

样例输入 #3

6
1 2 3 2 1 3

样例输出 #3

4

提示

样例 2 解释

一种最优的方案是:将所有元素都加上 \(2\),再将中间三个元素都加上 \(1\)

数据规模与约定

对于 \(30\) 分的数据,\(1 \le n \le 1000\)

对于 \(100\%\) 的数据,\(1 \le n \le 10^5\)\(0 \le a_i \le 10^9\)

单调栈的题感觉还是有点别扭
点击查看代码
#include<bits/stdc++.h>
using namespace std;
int n,a[100005],b[100005],st[100005],pt;
int main()
{
	ios::sync_with_stdio(false);
	cin>>n;
	for(int i=1;i<=n;i++)cin>>a[i];
	a[n+1]=0;
	int tot=0;
	for(int i=1;i<=n;i++)
	{
		while(pt>0&&st[pt]>a[i])pt--;
		if(pt>0&&st[pt]==a[i])continue;
		if(a[i])st[++pt]=a[i],tot++;
	}
	cout<<tot<<"\n";
	return 0;
} 
posted @ 2023-01-15 18:47  PKU_IMCOMING  阅读(55)  评论(0)    收藏  举报