腾讯2019.9.1笔试第二题

腾讯2019.9.1笔试第二题_第1张图片
一、暴力法
遍历i从0到n-1,每个i往后扩展。i=0时,low=w[0],sum=s[0],(0,0)时间段的评分为lowsum,maxvalue=lowsum,从(0,0)计算(0,1),如果w[1]sum,如果这次的lowsum大于maxvalue,则更新maxvalue。
时间复杂度为O(n^2)
这种方法只能a掉60%
二、矩形最大面积
要求到整个时间段的最高评分,所以low和sum的值都要尽可能大。
腾讯2019.9.1笔试第二题_第2张图片
以图为例:选第6个作为时间段里的最小值low,sum可以取到整个数组相加,其中任意一段子时间段计算出来sum1都小于sum。那么就可以遍历数组,每次取这天的评分为low,然后从这天往两边扩展,找到满足条件的最大时间段(其他时候的评分不能小于low),这段时间的总评分为sum,计算出这段时间的value=low*sum。这样就内似于求矩形的最大面积,因为每个柱子都有自己的值,所以看成每个柱子的值为该柱子的密度,求最大的矩形质量。
求最大矩形可参考https://leetcode-cn.com/problems/largest-rectangle-in-histogram/
https://leetcode-cn.com/problems/maximal-rectangle/solution/zui-da-ju-xing-by-leetcode/

w[i]表示前i+1天的评分,包括i+1天
所以对于每一个i要找到左右两边第一个使得w[j]

先将-1入栈,然后遍历0到n+1,如果w[i]>w[st.top],将i入栈,跳到数组下一个元素
如果w[i] 遍历完整个数组后,如果栈中还有元素,循环对栈顶元素做相同处理。

#include
#include
using namespace std;
int main()
{
	int w[]={5,3,9,6,7,8,1,2};
	int length=sizeof(w)/sizeof(w[0]);
	int *dp=new int[length+2];
	dp[0]=0;
	for(int i=1;i st;
	st.push(-1);
	int i;
	int maxvalue=0;
	for(i=0;imaxvalue?temp:maxvalue;
		}
		st.push(i);
		
	}
	
	while(st.size()!=1)
	{
		int low=w[st.top()];
		st.pop();
		int s=st.top()+1;
		int e=i+1;
		int sum=dp[e]-dp[s];
		int temp=low*sum;
		maxvalue=temp>maxvalue?temp:maxvalue;
		
	}
	
}

你可能感兴趣的:(笔记)