zoukankan      html  css  js  c++  java
  • E. Skyline Photo 线段树 + 单调栈 + dp

    E. Skyline Photo

    题目大意:

    (n) 栋楼房,每栋楼有一个高度 (h_i) 和美丽值 (b_i)
    现在,你需要把这 (n) 栋楼房划分成若干个连续段,每一个连续段的美丽值为该段中最矮的楼房的美丽值。总的划分美丽值为每个连续段的美丽值之和。

    你需要求出最大可能的总划分美丽值。

    题解:

    AC_CODE

    #include <bits/stdc++.h>
    #define lson (id<<1)
    #define rson (id<<1|1)
    #define inf 0x3f3f3f3f3f3f3f3f
    using namespace std;
    const int maxn = 3e5+10;
    typedef long long ll;
    ll maxs[maxn<<2],dp[maxn],lazy[maxn<<2];
    int h[maxn],b[maxn];
    int sta[maxn];
    void change(int id,ll val){
        maxs[id] += val;
        lazy[id] += val;
    }
    void push_down(int id){
        if(!lazy[id]) return ;
        change(lson,lazy[id]);
        change(rson,lazy[id]);
        lazy[id] = 0;
    }
    void push_up(int id){
        maxs[id] = max(maxs[lson],maxs[rson]);
    }
    void update(int id,int l,int r,int x,int y,ll val){
    //    printf("update: id = %d l = %d r = %d x = %d y = %d val = %lld
    ",id,l,r,x,y,val);
        if(x<=l&&y>=r){
            change(id,val);
            return ;
        }
        push_down(id);
        int mid = (l+r)>>1;
        if(x<=mid) update(lson,l,mid,x,y,val);
        if(y>mid) update(rson,mid+1,r,x,y,val);
        push_up(id);
    }
    ll query(int id,int l,int r,int x,int y){
        if(x<=l&&y>=r) {
            return maxs[id];
        }
        ll ans = -inf;
        push_down(id);
        int mid = (l+r)>>1;
        if(x<=mid) ans = max(ans,query(lson,l,mid,x,y));
        if(y>mid) ans = max(ans,query(rson,mid+1,r,x,y));
        return ans;
    }
    int main(){
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&h[i]);
        for(int i=1;i<=n;i++) scanf("%d",&b[i]);
        int now = 0;
        for(int i=1;i<=n;i++){
            while(now&&h[i]<h[sta[now]]){
                update(1,0,n,sta[now-1],sta[now]-1,-b[sta[now]]);
                now--;
            }
            update(1,0,n,sta[now],i-1,b[i]);
            sta[++now] = i;
            dp[i] = query(1,0,n,0,i-1);
    //        printf("dp[%d]=%lld
    ",i,dp[i]);
            update(1,0,n,i,i,dp[i]);
        }
        printf("%lld
    ",dp[n]);
        return 0;
    }
    
    
  • 相关阅读:
    rowkey设计原则和方法
    ubuntu安装及使用
    sqoop数据迁移
    Hive 自定义UDF操作步骤
    hive之数据导入导出
    MySQL优化
    MongoDB、Redis、elasticSearch、hbase的对比
    数据库基本操作
    count(*) 和 count(1)和count(列名)区别
    BigDecimal的运算——加减乘除
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/14565740.html
Copyright © 2011-2022 走看看