幹物妹小埋(吉首大學2019)---線段樹+dp

連接:https://ac.nowcoder.com/acm/contest/992/B
來源:牛客網

c++

在以前很火的一個動漫《幹物妹小埋》中,你們對小埋打遊戲喝可樂的印象十分的深入。
如今歐尼醬將小埋的快樂水所有分開藏在了傢俱的頂端。
小埋使出空中1080°轉身接戰術翻滾跳到任一傢俱上,她相信,只要她翻滾的足夠快,歐尼醬就跟不上她。
 
1.爲獲取夢幻開局,小埋一套技能能夠使她一開始掉落在任一傢俱上。
2.小埋家的傢俱按順序給出,每一個傢俱可跳可不跳,爲避開歐尼醬的追擊,小埋翻滾到某個傢俱上面後,只能向前繼續翻滾。
3.啓動超重力感應系統的小埋不會從較高的傢俱翻滾到較低的傢俱上。
4.因爲每一個傢俱上的快樂水都有對應的happy值,IQ==250的小埋會選擇一條happy值總和最大的路線。
那麼,最終小埋將得到的happy值總和是多少呢?

輸入描述:

第一行一個整數n(0<n<=200000),表示小埋家的傢俱數。

第二行n個整數,對於每一個整數ai, 0<=ai<=10^9,表示第i個傢俱的高度。

第三行n個整數,對於每一個整數vi, 0<=vi<=10^9,表示第i個傢俱上的快樂水的happy值。

輸出描述:

一個整數,表示小埋得到的happy值總和。
示例1

輸入

複製
6
2 1 1 3 3 4
3 1 1 1 1 1

輸出

複製
6


核心: 題意很可愛,但我只會線段樹吧,開心,1C...今天qixi, 想你!!
#include <bits/stdc++.h>
#define lson l, m, rt*2
#define rson m+1, r, rt*2+1
using namespace std;
typedef long long LL;
const int N=2e5+7;
LL tree[4*N];
int a[N], sort_a[N];
int val[N];
int n, cnt;
inline void pushup(int rt) {
    tree[rt]=max(tree[rt*2], tree[rt*2+1]);
}
LL query(int L, int R, int l, int r, int rt) {
    if (r<L||l>R) return 0;
    if (l>=L&&r<=R) return tree[rt];
    int m=(l+r)/2;
    return max (query(L, R, lson), query(L, R, rson));
}
void update(int k, LL key, int l, int r, int rt) {
    if (l==r)  {
        tree[rt]=max(tree[rt], key);
        return ;
    }
    int m=(l+r)/2;
    if (k<=m)
        update(k, key, lson);
    else 
        update(k, key, rson);
    pushup(rt);
}
int main()
{
    scanf("%d", &n);
    for (int i=1;i<=n;i++) {
        scanf("%d", &a[i]);
        sort_a[i]=a[i];
    }
    for (int i=1;i<=n;i++)
        scanf("%d", &val[i]);
    sort(sort_a+1, sort_a+1+n);
    cnt=1; 
    for (int i=2;i<=n;i++)
        if (sort_a[i]!=sort_a[cnt])
            sort_a[++cnt]=sort_a[i];
    LL ans=0;
    for (int i=n;i>=1;i--) {
        int k=lower_bound(sort_a+1, sort_a+1+cnt, a[i])-sort_a;
        //printf("%d\n",k);
        LL tmp=query(k, cnt, 1, cnt, 1)+val[i];
        ans=max(ans, tmp);
        update(k, tmp, 1, cnt, 1);
    }
    printf("%lld\n",ans);
    return 0;
}
相關文章
相關標籤/搜索