[Programming Question] The maximum value in the interval

Topic:
Given an array sequence, it is necessary to select an interval so that the interval is the largest value among all intervals calculated as follows:

The smallest number in the interval* The sum of all the numbers in the interval and the final program output the calculated maximum value, there is no need to output a specific interval. For a given sequence [6 2 1], according to the above formula, all the calculated values ​​that can be selected for each interval can be obtained:

[6] = 6 * 6 = 36;

[2] = 2 * 2 = 4;

[1] = 1 * 1 = 1;

[6,2] = 2 * 8 = 16;

[2,1] = 1 * 3 = 3;

[6, 2, 1] = 1 * 9 = 9;

It can be seen from the above calculation that the selected interval [6], the calculated value is 36, then the program output is 36.

All numbers in the interval are in the range of [0, 100];

enter:

第一行输入数组序列长度n,第二行输入数组序列。
对于 50%的数据,  1 <= n <= 10000;
对于 100%的数据, 1 <= n <= 500000;

Output:

输出数组经过计算后的最大值。

Example:

输入
3
6 2 1
输出
36

Analysis:
The simplest idea of ​​this question is to regard the element we are currently in as the smallest number in the entire interval. In the interval, all elements on the left and all elements on the right of this element are greater than this element.

Therefore, the problem is transformed into:
1. Traverse the entire array
2. When traversing, look for the first element L and R of the element x that is larger than this element to the left and right.
3. The calculated value of this interval is equal to x*sum (L+1,R-1), then look for the maximum value

Code:

#include <iostream>
#include <numeric>

using namespace std;

//局部变量存在栈区,无法存储这么大数组
int arr[500005];

int main()
{
    
    
	int n,max=0;
	cin >> n;
	for(int i=0;i<n;i++)
	{
    
    
		cin >> arr[i];
	}
	
	//开始遍历数组
	for(int i=0;i<n;i++)
	{
    
    
		int min = arr[i];
		//寻找最左值
		int L = i - 1;
		while (L>=0)
		{
    
    
			if(arr[L]>=min)
			{
    
    
				L--;
			}
			else
			{
    
    
				break;
			}
		}
		//别忘了加1
		L++;

		//寻找最右值
		int R = i + 1;
		while (R<n)
		{
    
    
			if (arr[R] >= min)
			{
    
    
				R++;
			}
			else
			{
    
    
				break;
			}
		}
		//别忘了减1
		R--;

		//求和
		int sum = accumulate(arr+L,arr+R+1, 0);

		//更新最大值
		max = (max > sum * min) ? max : sum * min;
	}
	cout << max;
	return 0;
}

For the accumulate() function, please refer to https://blog.csdn.net/weixin_43919932/article/details/113354255 for explanation

Note:
In the entire traversal process of the topic, obviously our time complexity is close to n^2. When n becomes very large, it will be extremely time-consuming. There is a good saying that programmers should squeeze every resource of the computer like a capitalist, and improve their own code efficiency (well, I said). Here is an explanation of the big guy's solution.

In the question, the value of n can be very large (1<=n<=500000), but one of the parameters is maintained in a small interval and involves the comparison of the maximum value, which is the value of each element. Value range (0<=x<=100).

In the outer loop, our essential work is to determine the minimum interval, so interval N and interval X seem to be replaceable.

Code:

#include <iostream>

using namespace std;

//局部变量存在栈区,无法存储这么大数组
int arr[500005];

int main()
{
    
    
	int n,max=0;
	cin >> n;
	for(int i=0;i<n;i++)
	{
    
    
		cin >> arr[i];
	}

	//arr[n]=0是为方便计算最后一节区间的计算值'
	arr[n] = 0;

	//假设有数组X[i],表示在数组arr中,元素都大于i的子区间的题目所需求的最大值,不过在只是求最大值的情况下这个数组可以省略
	for(int j=100;j>=1;j--)
	{
    
    
		int sum = 0;//临时存储和
		int min = j;//子区间最小值
		//对数组进行遍历,一次遍历我们可以找出多个区间
		for(int i=0;i<=n;i++)
		{
    
    
			//满足条件,则开始分割子区间
			if(arr[i]>=j)
			{
    
    
				sum += arr[i];
				min = (min < arr[i]) ? min : arr[i];
			}
			//不满足条件,子区间断开,计算子区间的值并更新最大值,但此时仍继续遍历,寻找下一个满足子区间
			else
			{
    
    
				max = (max > sum * min) ? max : sum * min;

				sum = 0;
				min = j;
			}
		}
	}
	cout << max;
	return 0;
}

Guess you like

Origin blog.csdn.net/qq_43530773/article/details/115010361