(区间覆盖问题)P5019 [NOIP2018 提高组] 铺设道路和Educational Codeforces Round 158 (Rated for Div. 2)

区间覆盖问题

这里Educational Codeforces Round 158 (Rated for Div. 2)b题
[NOIP2018 提高组] 铺设道路两道典型题目,本质是相同的。
这里由于题目多次出现,特此记录。

解题思路:

首先我们得对区间做划分,那么划分思路可以是从小到大也可以是从大到小的异常点来做划分(我这是由大到小),再着我们要对两个区间做处理(就是异常点),最后累加每个区间最大值就ok。
区间最大值 就是要处理一个区间的最多需要次数
假如一组数据为5 3 2 1 4 3,那么就可以划分两个区间 分别为5 3 2 1 和 4 3。我们可以知道第一个区间最大值为5,第二区间最大值为4,但由于它前面那个区间的末尾数不为0,所以我们应该对最大值减去前一个区间的末位数(也就是最小值)得到最大区间值为3。
那么答案就是每个区间最大值累加。

代码如下
#include <iostream>
#include <string>
#include <math.h>
#include <algorithm>
using namespace std;
int a[200001];

int main() {
	int n;
	cin >> n;
	for (int i = 1; i <= n; i++) {
		int m;
		long long num = 0;
		cin >> m;
		for (int j = 1; j <= m; j++) {
			cin >> a[j];
		}
		for (int j = 1; j <= m; j++) {
			if (a[j] == 0) {
				break;
			}
			a[j]--;
		}
		for (int j = 1; j <= m ; j++) {
			if (a[j] == 0) {
				continue;
			} else {
				long long  c = a[j] - a[j - 1];
				while (a[j] >= a[j + 1]) {
					j++;//不知道为什么编译器上和cf上没下面那个判断条件也能过
					if(j>m){
						break;
					}
				}
				num += c ;
			}
		}
		cout << num  << endl;
	}
}
posted @ 2024-01-21 21:11  拍手称快  阅读(15)  评论(0编辑  收藏  举报