• 51Nod


    51Nod - 1102 面积最大的矩形

    有一个正整数的数组,化为直方图,求此直方图包含的最大矩形面积。例如 2,1,5,6,2,3,对应的直方图如下:
     
     
    面积最大的矩形为5,6组成的宽度为2的矩形,面积为10。
     
    Input
    第1行:1个数N,表示数组的长度(0 <= N <= 50000)
    第2 - N + 1行:数组元素A[i]。(1 <= A[i] <= 10^9)
    Output
    输出最大的矩形面积
    Input示例
    6
    2
    1
    5
    6
    2
    3
    Output示例
    10

    题解: 

        (1), 第一种方法使用 rmq 的方法,建立线段树sparse table,然后再搜两端点找到最小值,扩充为该端点与之最小值的乘积。可是只ac了60%。 

        (2), 第二种方法是采用经典的 left_array 和 right_array 两个数组,找到每一个数组元素可以扩展到的最大值。 

    #include <iostream>
    #include <cstdio> 
    #include <cstring> 
    #include <algorithm>
    #include <cmath>  
    using namespace std; 
    const int MAXN = 50000 + 10; 
    int n, m, num[MAXN], dp[MAXN][30], dp_p[MAXN][30]; 
    long long ans; 
    
    void build(){
    	for(int i=0; i<n; ++i){
    		dp[i][0] = num[i]; 
    		dp_p[i][0] = i; 
    	} 
    	for(int i=1; (1<<i)<=n; ++i){
    		for(int j=0; j+(1<<i)-1< n; ++j){
    			if(dp[j][i-1] > dp[j+(1<<(i-1))][i-1]){
    				dp[j][i] = dp[j+(1<<(i-1))][i-1]; 
    				dp_p[j][i] = dp_p[j+(1<<(i-1))][i-1]; 
    			}else{
    				dp[j][i] = dp[j][i-1]; 
    				dp_p[j][i] = dp_p[j][i-1]; 
    			}
    		}
    	}
    }
    
    void Search(int l, int r){
    	if(l >= r){ 
    		return; 
    	}
    	int minv, min_j, k = (int)(log2(1.0*(r - l + 1))); 
    	if(dp[l][k] < dp[r-(1<<k)+1][k]){
    		minv = dp[l][k]; 
    		min_j = dp_p[l][k]; 
    	}else{
    		minv = dp[r-(1<<k) + 1][k]; 
    		min_j = dp_p[r-(1<<k) + 1][k]; 
    	} 
    	if(ans < (long long)(minv*(r - l + 1))){
    		ans = (long long)(minv * (r-l + 1)); 
    	}
    	Search(l, min_j - 1); 
    	Search(min_j + 1, r); 
    }
    
    int main(){
    	freopen("in.txt", "r", stdin); 
    
    	while(scanf("%d", &n) != EOF){
    		ans = 0; 
    		for(int i=0; i<n; ++i){
    			scanf("%d", &num[i]); 
    			ans = max(ans, (long long)(num[i])); 
    		} 
    		build(); 
    		Search(0, n-1); 
    		printf("%lld
    ", ans );
    	} 
    	return 0; 
    }
    

      

    #include <iostream>
    #include <cstdio> 
    #include <cstring> 
    #include <algorithm>
    #include <cmath>  
    using namespace std; 
    const int MAXN = 50000 + 10; 
    
    long long ans, num[MAXN], l[MAXN], r[MAXN];  
    
    int main(){
    
    	int n, k, i; 
    	scanf("%d", &n); 
    	for(i=1; i<=n; ++i){
    		scanf("%lld", &num[i]); 
    	}
    	num[0] = num[n+1] = 0; 
    	for(i=1; i<=n; ++i){
    		k = i - 1;
    		while(num[i] <= num[k]){
    			k = l[k] - 1; 
    		}
    		l[i] = k + 1; 
    	}
    	for(i=n; i>=1; --i){
    		k = i + 1; 
    		while(num[i] <= num[k]){
    			k = r[k] + 1; 
    		}
    		r[i] = k - 1; 
    	}
    	ans = 0; 
    	for(i=1; i<=n; ++i){
    		if(ans < num[i]*(r[i] - l[i] + 1)){
    			ans = num[i]*(r[i] - l[i] + 1); 
    		}
    	}
    	printf("%lld
    ",  ans); 
    	return 0; 
    }
    

      

  • 相关阅读:
    需求工程阅读笔记03
    需求工程阅读笔记02
    【Augmented Reality】增强现实中的光学透射式头盔显示器的标定进阶
    基于单个RGB摄像头的手势识别程序设计与实现
    将Vuforia程序发布到Windows10系统的基本流程
    基于Unity3D 的Vuforia SDK开发基础教程
    微软KinectV2深度传感器在Ubuntu上的配置和使用
    Windows 10(64位)配置Caffe运行环境的基本流程
    Ubuntu14.04 64位配置Caffe 教程(基于CUDA7.5)
    空间增强现实——基于贝塞尔曲面的异形表面投影变形技术
  • 原文地址:https://www.cnblogs.com/zhang-yd/p/6920093.html
Copyright © 2020-2023  润新知