ccfcsp 202109-2 非零段划分,差分

题目传送门

题目描述



算法求解

分析

利用差分的思想,每当遇到一个 a[i] < a[i+1]的时候,就将对应的对于 p = a[i-1] + 1a[i]这个区间内的所有p 的非零划分的数量+1(这就转换到了差分的思路)

然后使用前缀和统计p所有可能的取值对应的非零段的数量,去最大值即可

注意这里只需要统计上升段(或者只统计下降段也可以)

代码

只统计上升段

#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
const int N = 500010;
int di_max;
vector<int> peeks; // 所有峰值点 
int a[N];
int b[N];
int n;
void add(int l, int r)
{
	b[l] += 1;
	b[r+1] -= 1; 
}
int main()
{
	
//	使用差分的思路
	scanf("%d", &n);
	for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
	
	int maxa = 0;
	for(int i = 1; i <= n; i++)
	{
		if(a[i-1] < a[i])
		{
			add(a[i-1] + 1, a[i]); // 对于 p = a[i-1] + 1  到 a[i] 这个区间内的所有p,其非零段的数量都+1 
		}
		
		if(maxa < a[i]) maxa = a[i];
	}
	
	int res = 0;
	for(int i = 1; i <= maxa; i++)
	{
		b[i] += b[i-1];
		res = max(res, b[i]);	
	} 
	cout << res << endl;
	return 0;
    
    
    
	/*暴力60 
	scanf("%d", &n);
	int maxx = 0; 
	for(int i = 1; i <= n; i++) 
	{
		scanf("%d", &a[i]);
		if(a[i] > maxx) maxx = a[i];
	} 
	
	int res = 0; 
	for(int p = 1; p <= maxx; p++)
	{
		// 小于p的都视为0
		int cnt = 0; //段数
		int i = 0;
		while(i <= n)
		{
			while(a[i] < p) i++; // p段
			if(i > n) break;
			
			while(a[i] >= p) i++;
			cnt++; // 非p段 
			 
		} 
//		cout << cnt << endl; 
		res = max(res, cnt);
		  
	}
	cout << res;
	
	return 0;
	*/
	
	/* 得分为0 
	for(int i = 1; i <= n; i++)
	{
		if(a[i] > a[i-1] && a[i] > a[i+1]) peeks.push_back(a[i]);
		
		if(a[i] <= a[i-1] && a[i] <= a[i+1]) 
		{
			if (a[i] > di_max)
			 di_max = a[i];
		}
	}
	int res = 0;
	for(auto t : peeks)
	{
		if(t > di_max) res++;
	}
	cout << res;
	return 0;
	*/
} 

只统计下降段

#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
const int N = 500010;
int di_max;
vector<int> peeks; // 所有峰值点 
int a[N];
int b[N];
int n;
void add(int l, int r)
{
	b[l] += 1;
	b[r+1] -= 1; 
}
int main()
{
	
//	使用差分的思路
	scanf("%d", &n);
	for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
	
	int maxa = 0;
	for(int i = 0; i <= n; i++)
	{
		if(a[i] > a[i+1])
		{
			add(a[i+1] + 1, a[i]); 
		}
		
		if(maxa < a[i]) maxa = a[i];
	}
	
	int res = 0;
	for(int i = 1; i <= maxa; i++)
	{
		b[i] += b[i-1];
		res = max(res, b[i]);	
	} 
	cout << res << endl;
	return 0;
} 

时间复杂度

\(O(n)\)

参考文章

https://blog.csdn.net/qq_51282224/article/details/122475544

posted @ 2022-03-04 20:05  VanHope  阅读(150)  评论(0编辑  收藏  举报