首页 > 其他分享 >AcWing 3662. 最大上升子序列和

AcWing 3662. 最大上升子序列和

时间:2023-06-28 09:22:41浏览次数:43  
标签:10 前缀 3662 样例 序列 我们 本题 AcWing

\(AcWing\) \(3662\). 最大上升子序列和

一、题目描述

给定一个长度为 \(n\) 的整数序列 \(a_1,a_2,…,a_n\)。

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

请问这个 最大值 是多少?

输入格式
第一行包含整数 \(n\)。

第二行包含 \(n\) 个整数 \(a_1,a_2,…,a_n\)。

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

数据范围
对于前三个测试点,\(1≤n≤4\)。

对于全部测试点,\(1≤n≤10^5,1≤a_i≤10^9\)。

输入样例1

2
100 40

输出样例1

100

输入样例2

4
1 9 7 10

输出样例2

20

样例解释
对于样例 \(1\),我们只选取 \(100\)。

对于样例 \(2\),我们选取 \(1,9,10\)。

二、前置知识

1. 离散化

2. 树状数组 or 线段树 (用于维护前缀的信息)

3. 最长上升子序列 AcWing 895. 最长上升子序列

三、分析

首先这道题在不考虑优化的情况下是一道最长上升子序列板子题,不会的先去看一下 这道题 ,由于本题数据范围过大,我们需要考虑如何优化,这也是本题的 难点 所在。

我们先从\(DP\)的角度讨论一下这题的朴素写法

本题的状态转移方程见上图,显然,我们在执行状态方程的途中需要寻找某一个前缀的最大值,这使得我们每次执行方程都会遍历一遍前面的每一个数,这就导致了\(O(n^2)\) 的时间复杂度,我们需要考虑一下如何将这一维优化掉。

由于我们每次寻找的\(f(k)_{max}\)是一个前缀中的最大值,我们很容易可以想到树状数组或者线段树,来动态的维护前缀的最大值吗,这样我们每次查询就可以从\(O(n)\)优化到\(O(logn)\)

那么我们如何来维护这样一个前缀呢?

比较容易想到的是将\(f(i)\)维护到下标\(i\),如下图所示

但是这样做在本题中是否行得通呢?

先说结论,本题不可以这样维护,由于题目明确规定,我们要找的子序列为单调上升子序列,所以必须满足一个条件\(a_i>a_k\),如果我们维护上面这样一个关系,虽然可以让我们找到前缀中最大的一个\(f(k)\),但是我们却无法保证\(a_i>a_k\)。

那我们如何维护呢?

我们考虑将\(f(i)\)维护到下标\(a_i\),如下图所示

如果我们采取这种维护策略,若\(a_2>a_i\),则我们在查询\(a_i\)的前缀时,就永远也无法找到\(f(2)\),这样就保证了\(a_i>a_k\) 这个条件始终是成立的。

但是,到这里还有最后一个问题,\(1≤ai≤109\),如果我们直接维护,那么需要开一个大小为\(10^9\)的数组才可以做到,这显然是不可以接受的,同时我们发现\(1≤n≤10^5\),这说明我们可以离散化一下,把每一个\(a_i\)按照相对位置关系,一一映射到\(1≤n≤10^5\) 这个区间上,若文字难以理解,可以看下面的图。

离散化需要去重,由于本题的答案是取决于单调上升子序列并且子序列内部元素不能相等,所以去重不影响答案,我们需要的只是每个元素的相对位置不变,以及相对位置信息。

四、\(Code\)

#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
typedef long long LL;      // 本题中 a 的上线是 10 ^ 9,故答案可能会超过 int 的上限
#define lowbit(x) (x & -x) // lowbit函数模板

int n, a[N];

int b[N], bl;  // 离散化数组
LL tr[N], res; // 树状数组,答案

void add(int x, LL c) {
    for (; x <= bl; x += lowbit(x)) tr[x] = max(tr[x], c);
}

// 查询x范围内,元素和最大值
LL query(int x) {
    LL res = 0;
    for (; x; x -= lowbit(x)) res = max(res, tr[x]);
    return res;
}

int main() {
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", a + i);
        b[i] = a[i];
    }
    // 离散化
    sort(b, b + n);
    bl = unique(b, b + n) - b;

    for (int i = 0; i < n; i++) {                     // 枚举原始数组
        int k = lower_bound(b, b + bl, a[i]) - b + 1; // 二分查找a[i]离散化后的值,注意配合树状数组+1
        /*
        状态转移方程:f[i]=a[i]+max(f[j]) (0<=j<i,a[j]<a[i])
        f[i]: f
        a[i]: a[i]
        max(f[j]):query(k - 1) 表示k-1范围内元素和最大值
        */
        LL f = a[i] + query(k - 1);
        res = max(res, f); // 更新最大值
        add(k, f);         // 更新树状数组
    }
    printf("%lld\n", res);

    // 下面的代码也可以AC
    // printf("%lld\n", query[bl]);
    return 0;
}

标签:10,前缀,3662,样例,序列,我们,本题,AcWing
From: https://www.cnblogs.com/littlehb/p/17510484.html

相关文章

  • R语言从经济时间序列中用HP滤波器,小波滤波和经验模态分解等提取周期性成分分析|附代码
    全文下载链接:http://tecdat.cn/?p=9350最近我们被客户要求撰写关于经济时间序列的研究报告,包括一些图形和统计输出。经济时间序列的分析通常需要提取其周期性成分。这篇文章介绍了一些方法,可用于将时间序列分解为它们的不同部分 ( 点击文末“阅读原文”获取完整代码数据*******......
  • java反序列化与反序列化
    java反序列化漏洞JAVA反序列化漏洞是由于开发者重写了readObject方法,该readObject方法方法调用了别的方法,最终执行到了例如Transfrom方法的危险方法java序列化过程:调用一个函数进行序列化,存放到一个文件内,再将文件反序列化回来,涉及到文件的读写序列化与反序列化序列化:Objec......
  • PHP序列化与反序列化
    PHP反序列化漏洞序列化和反序列化本身是为了实现数据在网络上完整高效的传输,但是由于反序列化过程中,对象的魔术方法会自动调用,魔术方法本身调用了别的方法,最终呈现一种链式调用,直到执行任意的代码或者命令。序列化与反序列化seriallization序列化:将对象转化为便于传输的格式,......
  • odoo14中生成序列号
    #大货类型的制造订单,序列号格式为“MO年份后两位四位顺序码”,例:MO230001#PPS样类型的制造订单,序列号格式为“MO年份后两位四位顺序码-Sample“,例:MO230001-Sample 在Odoo中,您可以使用XML来定义一个ir.sequence数据,以生成满足特定格式的序列号。以下是按照您提供的格式创......
  • SQLServer Core 序列号使用CPU限制的处理
    SQLServerCore序列号使用CPU限制的处理背景有客户是SQLSERVER的数据库.说要进行一下压测.这边趁着最后进行一下环境的基础搭建工作.然后在全闪的环境上面搭建了一个Windows2019+SQL2019的环境发现一个挺好的地方.SQLSERVER会提示,如果使用enterprise的序列号的话仅能......
  • LeetCode 128. 最长连续序列
    为什么这题我都不会,脑袋有点累,状态真差classSolution{public:intlongestConsecutive(vector<int>&nums){unordered_set<int>s(nums.begin(),nums.end());//记录数字是否出现过intres=0;for(autoi:nums)//枚举每个数字,查看以当前数字......
  • m 序列(最长线性反馈移位寄存器序列)详解
    本专栏包含信息论与编码的核心知识,按知识点组织,可作为教学或学习的参考。markdown版本已归档至【Github仓库:<https://github.com/timerring/information-theory>】或者公众号【AIShareLab】回复信息论获取。m序列(最长线性反馈移位寄存器序列)线性反馈移位寄存器的特征多项式......
  • 基于Logistic混沌序列的图像加解密算法matlab仿真
    1.算法仿真效果matlab2022a仿真结果如下:2.算法涉及理论知识概要基于logistic混沌序列的图像加解密算法是一种基于混沌理论的加密算法,它通过混沌序列生成的随机数来改变图像的像素值,从而达到加密的目的。本文将详细介绍基于logistic混沌序列的图像加解密算法。混沌理论是指一类......
  • 基于Logistic混沌序列的图像加解密算法matlab仿真
    1.算法仿真效果matlab2022a仿真结果如下:     2.算法涉及理论知识概要       基于logistic混沌序列的图像加解密算法是一种基于混沌理论的加密算法,它通过混沌序列生成的随机数来改变图像的像素值,从而达到加密的目的。本文将详细介绍基于logistic混沌序列的......
  • 07前后端项目上传gitee,后端多方式登录接口,发送短信功能,发送短信封装,短信验证码接口,短
    1前后端项目上传到gitee#公司里: -前端一个仓库---》一个团队-后端一个仓库---》一个团队-微服务:两三个人一个服务---》一个项目一个仓库-网上开源软件,前后端都在一起#在远端建立前端仓库#本地代码提交到远成仓库2后端多方式......