Codeforces Round #709 (Div. 2, based on Technocup 2021 Final Round) E. Skyline Photo

题目链接:https://codeforces.com/contest/1484/problem/E
                      E. Skyline Photo

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 nn buildings in the city, the ii-th of them has positive height hihi. All nn building heights in the city are different. In addition, each building has a beauty value bibi. 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 bibi 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.

Input

The first line contains an integer nn (1n31051≤n≤3⋅105), the number of buildings on the skyline.

The second line contains nn distinct integers h1,h2,,hnh1,h2,…,hn (1hin1≤hi≤n). The ii-th number represents the height of building ii.

The third line contains nn integers b1,b2,,bnb1,b2,…,bn (109bi109−109≤bi≤109). The ii-th number represents the beauty of building ii.

Output

Print one number representing the maximum beauty Alice can achieve for a valid set of photos of the skyline.

Examples
input
Copy
5
1 2 3 5 4
1 5 3 2 4
output
Copy
15
input
Copy
5
1 4 3 2 5
-3 4 -10 2 7
output
Copy
10
input
Copy
2
2 1
-2 -3
output
Copy
-3
input
Copy
10
4 7 3 2 5 1 9 10 6 8
-4 40 -46 -8 -16 4 -10 41 12 3
output
Copy
96
Note

In the first example, Alice can achieve maximum beauty by taking five photos, each one containing one building.

In the second example, Alice can achieve a maximum beauty of 1010 by taking four pictures: three just containing one building, on buildings 11, 22 and 55, each photo with beauty 3−3, 44 and 77 respectively, and another photo containing building 33 and 44, with beauty 22.

In the third example, Alice will just take one picture of the whole city.

In the fourth example, Alice can take the following pictures to achieve maximum beauty: photos with just one building on buildings 11, 22, 88, 99, and 1010, and a single photo of buildings 33, 44, 55, 66, and 77.

题目描述:给出n个房子,每个房子有高度h和美丽值b。n个房子可以任意划分成若干个连续的子集。每个划分出来的子集的值就是高度最低的房子的美丽值b。问子集的值总和最大时多少。

思路:比较容易想到的是,左到右扫一遍,在某一个划分的子集中,若当前房子 i 比前面的房子矮,那么前面比他高的房子都不会再被算入当前子集的值。所以可以维护一个单调栈(维护房子序号),把前面比 i 高的房子删掉,因为他们不会再被用到。

用一个数组如best_ans_where_hi[ j ]表示,当前房子为 i ,以栈顶元素 j 为结尾时,前 j 个房子用来划分得到的最佳答案。因为有矮房子 i 的存在,使得第 j 个到第 i 个房子都可以作为一个划分区间。所以,每当删除一个较高房子时,都更新一下该数组。

再用一个数组max_in _stack[ ]维护在之前出栈的某个 j 中得到的最佳划分 + 第 j 到第 i 个房子的作为一个划分区间的权值 (也就是b[i],因为i最矮)。

很显然以 i 结尾的答案就是当前栈顶的max_in_stack。

讲的有点绕,结合代码更好理解。

#include<cstdio>
#include<iostream>
#include<deque>
#include<cstring>
#include<bits/stdc++.h>
#define sd(x) scanf("%d",&x)
#define lsd(x) scanf("%lld",&x)
#define sf(x) scanf("%lf",&x)
#define ms(x,y) memset(x,y,sizeof x)
#define fu(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define all(a) a.begin(),a.end()
#define range(a,x,y) a+x,a+y+x
using namespace std;
using namespace __gnu_cxx;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<ll,ll> P;
const int N=3e5+99;
const ll INF=1e9+7;
int h[N],b[N],st[N];
ll max_in_stack[N],dp[N],best_ans_where_hi[N];
int main() 
{
    int n;cin>>n;
    fu(i,1,n) cin>>h[i];
    fu(i,1,n) cin>>b[i];
    int tt=0;
    max_in_stack[0]=-INF;
    fu(i,1,n)
    {
        ll tmp=dp[i-1];
        while(tt&&h[st[tt]]>h[i])
        {
            tmp=max(tmp,best_ans_where_hi[tt]);
            tt--;
        }
        st[++tt]=i;
        best_ans_where_hi[tt]=tmp;//以栈顶元素为结尾,划分的最佳答案
        max_in_stack[tt]=max(max_in_stack[tt-1],tmp+b[i]);
        dp[i]=max_in_stack[tt];
    }
    printf("%lld\n",dp[n]);
    return 0;
}

 

posted on 2021-03-26 00:18  Aminers  阅读(102)  评论(0编辑  收藏  举报

导航