• hdu 1506 Largest Rectangle in a Histogram(DP)


    题意:

    有一个柱状图,有N条柱子。每一条柱子宽度都为1,长度为h1...hN。

    在这N条柱子所构成的区域中找到一个最大面积,每平方米3块钱,问最多赚多少钱。

    输入:

    1<=N<=100000

    0<=hi<=1000000000

    思路:

    N很大,肯定得用一个O(N)或O(NLOGN)的算法,,

    假如这个面积的长是从第i条柱子到第j条柱子,宽则一定是第i条柱子到第j条柱子中最矮的那条柱子的高度。

    而我们站在那根最矮的柱子向左看,第i-1条的柱子一定是小于当前柱子的,否则可以加进去。向右看同理。

    所以了,咱们就枚举每一根柱子,把它当作一段区域中的最矮的那根,然后向左向右极大地去延伸。

    具体如何延伸呢,

    假设left[i]表示第i根向左最多延伸到的柱子编号

    假设现在枚举到第k根柱子,如果第k-1根柱子高度小于本身,则向左没法延伸。如果大于等于,则从left[i-1]到i-1都是大于等于本身的,只需从left[i-1]-1开始继续往前比较,这里就可以用while循环实现了。

    向右同理。

    看代码,

    代码:

    int const N = 100005;
    
    int h[N], leftt[N], rightt[N];
    
    
    int main(){
    
        int n;
        while(cin>>n,n){
    
            mem(leftt,0);
            mem(rightt,0);
    
            rep(i,1,n){
                scanf("%d",&h[i]);
                leftt[i] = rightt[i] = i;
            }
            rep(i,2,n){
                if(h[i]<=h[i-1]){
                    leftt[i] = leftt[i-1];
                    while(leftt[i]>1 && h[i]<=h[leftt[i]-1]){
                        leftt[i] = leftt[leftt[i]-1];
                    }
                }
            }
            rep2(i,n-1,1){
                if(h[i]<=h[i+1]){
                    rightt[i] = rightt[i+1];
                    while(rightt[i]<n && h[i]<=h[rightt[i]+1]){
                        rightt[i] = rightt[rightt[i]+1];
                    }
                }
            }
    
            ll ans = 0;
            rep(i,1,n){
                ll temp = (ll)(rightt[i]-leftt[i]+1)*(ll)h[i];
                if(temp>ans) ans = temp;
            }
    
            printf("%I64d
    ",ans);
    
        }
    
        return 0;
    }
  • 相关阅读:
    贪心策略---不重叠的区间个数
    贪心策略---分配饼干
    双指针---最长子序列
    双指针---回文字符串
    双指针---反转字符串中的元音字符
    双指针---两数平方和
    双指针---有序数组的TWO SUM
    排序---小结
    排序---桶排序
    变量的解构赋值
  • 原文地址:https://www.cnblogs.com/fish7/p/4230011.html
Copyright © 2020-2023  润新知