zoukankan      html  css  js  c++  java
  • 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; 
    }
    

      

  • 相关阅读:
    HDU5195 线段树+拓扑
    Codeforces Round #328 (Div. 2)D. Super M 虚树直径
    HDU5489 LIS变形
    BZOJ 1787: [Ahoi2008]Meet 紧急集合 LCA
    Codeforces Round #330 (Div. 2)B. Pasha and Phone 容斥
    Codeforces Round #330 (Div. 2) D. Max and Bike 二分
    Codeforces Round #277 (Div. 2) E. LIS of Sequence DP
    Codeforces Round #277 (Div. 2) D. Valid Sets DP
    内存对齐
    mui列表跳转到详情页优化方案
  • 原文地址:https://www.cnblogs.com/zhang-yd/p/6920093.html
Copyright © 2011-2022 走看看