zoukankan      html  css  js  c++  java
  • CF1482E Skyline Photo

    Description

    Alice is visiting New York City. To make the trip fun, Alice will take photos of the city skyline and give the set of photos as a present to Bob. However, she wants to find the set of photos with maximum beauty and she needs your help.

    There are $n$ buildings in the city, the $i$-th of them has positive height $h_i$. All $n$ building heights in the city are different. In addition, each building has a beauty value $b_i$. Note that beauty can be positive or negative, as there are ugly buildings in the city too.

    A set of photos consists of one or more photos of the buildings in the skyline. Each photo includes one or more buildings in the skyline that form a contiguous segment of indices. Each building needs to be in exactly one photo. This means that if a building does not appear in any photo, or if a building appears in more than one photo, the set of pictures is not valid.

    The beauty of a photo is equivalent to the beauty $b_i$ of the shortest building in it. The total beauty of a set of photos is the sum of the beauty of all photos in it. Help Alice to find the maximum beauty a valid set of photos can have.

    Solution

    设$dp_i$表示考虑前$i$个建筑的答案,求出$i$前面的第一个高度比$h_i$小的位置$j$,可以用单调队列求出

    如果$j$与$i$在同一张照片,此时的答案就是$dp_j$

    如果$j$与$i$不在同一张照片,因为$i$是$(j,i]$中最低的,所以此时的答案就是$dp_k+b_i$,其中$j leq k < i$,可以用线段树求出

    时间复杂度$O(n log n)$

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    int n,h[300005],b[300005],sta[300005],top,L[300005];
    long long dp[300005],val[1200005];
    const long long inf=0x7f7f7f7f7f7f7f7f;
    inline int read(){
        int f=1,w=0;
        char ch=0;
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9')w=(w<<1)+(w<<3)+ch-'0',ch=getchar();
        return f*w;
    }
    void build(int i,int l,int r){
        val[i]=-inf;
        if(l==r)return;
        int mid=l+r>>1;
        build(i<<1,l,mid),build(i<<1|1,mid+1,r);
    }
    long long query(int i,int l,int r,int L,int R){
        if(L<=l&&r<=R)return val[i];
        int mid=l+r>>1;
        long long ret=-inf;
        if(L<=mid)ret=max(ret,query(i<<1,l,mid,L,R));
        if(R>mid)ret=max(ret,query(i<<1|1,mid+1,r,L,R));
        return ret;
    }
    void update(int i,int l,int r,int p,long long v){
        if(l==r){val[i]=max(val[i],v);return;}
        int mid=l+r>>1;
        if(p<=mid)update(i<<1,l,mid,p,v);
        else update(i<<1|1,mid+1,r,p,v);
        val[i]=max(val[i<<1],val[i<<1|1]);
    }
    int main(){
        n=read();
        for(int i=1;i<=n;i++)h[i]=read();
        for(int i=1;i<=n;i++)b[i]=read();
        build(1,0,n),dp[0]=-inf,update(1,0,n,0,0);
        for(int i=1;i<=n;i++){
            while(top&&h[sta[top]]>=h[i])--top;
            L[i]=sta[top],sta[++top]=i,dp[i]=max(query(1,0,n,L[i],i-1)+b[i],dp[L[i]]),update(1,0,n,i,dp[i]);
        }
        printf("%lld
    ",dp[n]);
        return 0;
    }
    Skyline Photo
  • 相关阅读:
    删除系统盘符
    响应式设计 @media
    精通CSS 学习笔记
    兼容性
    css border-collapse
    angular.js学习 ui-router 0.2.15
    javascript的简易发布/订阅模式
    javascript 切换上下文,事件绑定中改变this指向
    SpringMVC:提交日期类型报400错误解决方法
    解决Spring Mvc中接受参数绑定重名的方法
  • 原文地址:https://www.cnblogs.com/JDFZ-ZZ/p/14582382.html
Copyright © 2011-2022 走看看