ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

3662. 最大上升子序列和

2021-06-15 19:35:48  阅读:175  来源: 互联网

标签:include 3662 int LL 样例 a2 序列 上升


给定一个长度为 nn 的整数序列 a1,a2,…,ana1,a2,…,an。

请你选出一个该序列的严格上升子序列,要求所选子序列的各元素之和尽可能大。

请问这个最大值是多少?

输入格式

第一行包含整数 nn。

第二行包含 nn 个整数 a1,a2,…,ana1,a2,…,an。

输出格式

输出最大的上升子序列和。

数据范围

对于前三个测试点,1≤n≤41≤n≤4。
对于全部测试点,1≤n≤105,1≤ai≤1091≤n≤105,1≤ai≤109。

输入样例1:

2
100 40

输出样例1:

100

输入样例2:

4
1 9 7 10

输出样例2:

20

样例解释

对于样例 11,我们只选取 100100。

对于样例 22,我们选取 1,9,101,9,10。

算法 —— 离散化 + 树状数组
用 sum[i] 表示以 a[i] 为结尾的最大单调子序列和
用 maxSum[x] 表示以 x 为结尾值的最大单调子序列和

暴力解法:

for (int i = 1; i <= n; i++) {
    sum[i] = a[i];
    for (int j = 1; j < a[i]; j++) {
        sum[i] = max(sum[i], maxSum[j] + a[i]);
    }
    maxSum[a[i]] = max(maxSum[a[i]], sum[i]);
}

可以使用树状数组优化,将 maxSum 优化成单点修改、区间查询的树状数组。
需要注意的是,数据的范围为 1e9,比较大,还需要进行离散化。

#include <algorithm>
#include <cstring>
#include <iostream>
#include <unordered_map>
using namespace std;
const int N = 1e5 + 10;
typedef long long LL;
LL n, a[N], b[N], sum[N], maxSum[N];
unordered_map<int, LL> mp;
LL c[N];
// 查询前缀和:查询序列 a 第 1~x 个数的和
LL ask(LL x) {
    LL ans = 0;
    for (; x; x -= x & -x) ans = max(ans, c[x]);
    return ans;
}
// 单点增加:给序列中的一个数 a[x] 加上 y
// 算法:自下而上每个节点都要增加 y
void add(int x, LL y) {
    for (; x <= n; x += x & -x) c[x] = max(c[x], y);
}

int main() {
    cin >> n;
    for (int i = 1; i <= n; i++) cin >> a[i];

    // 离散化
    memcpy(b, a, sizeof a);
    sort(b + 1, b + n + 1);
    LL m = 0;
    for (int i = 1; i <= n; i++) {
        if (!mp.count(b[i]))
            mp[b[i]] = ++m;
    }

    // DP 过程,使用树状数组优化
    for (int i = 1; i <= n; i++) {
        sum[i] = max(mp[a[i]], ask(mp[a[i]] - 1) + a[i]);
        add(mp[a[i]], sum[i]);
        // sum[i] = a[i];
        // for (int j = 1; j < a[i]; j++) {
        //     sum[i] = max(sum[i], maxSum[j] + a[i]);
        // }
        // maxSum[a[i]] = max(maxSum[a[i]], sum[i]);
    }

    LL ans = 0;
    for (int i = 1; i <= n; i++) {
        ans = max(ans, sum[i]);
    }
    cout << ans << endl;
    return 0;
}

 

标签:include,3662,int,LL,样例,a2,序列,上升
来源: https://www.cnblogs.com/kayiko/p/14886781.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有