【最大上升子序列和】

2024-09-02 22:04
文章标签 最大 序列 上升

本文主要是介绍【最大上升子序列和】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目

在这里插入图片描述


前置芝士

1. erase 函数
erase(iterator pos):删除单个元素,其中 pos 是要删除元素的迭代器。
erase(iterator first, iterator last):删除从 first 到 last(不包括 last)之间的所有元素。

2. unique 函数
unique 函数用于去除容器中相邻的重复元素,并返回一个迭代器,指向去重后容器中最后一个有效元素的下一个位置。
unique(iterator first, iterator last):处理从 first 到 last(不包括 last)之间的元素。
3. lower_bound 函数
lower_bound(iterator first, iterator last, const T& value):在从 first 到 last(不包括 last)之间的元素中查找第一个大于等于 value 的元素的位置,返回对应迭代器it,如果不存在则返回.end()


思路

如果数据足够小,可以采用二重循环+dp

状态定义:
f [ i ] 对应 1 到 i 号元素形成的序列中,包括第 i 个元素的所有上升子序列的集合 f[i]对应1到i号元素形成的序列中,包括第i个元素的所有上升子序列的集合 f[i]对应1i号元素形成的序列中,包括第i个元素的所有上升子序列的集合
f [ i ] 表示和的最大值 f[i]表示和的最大值 f[i]表示和的最大值

状态转移:
f [ j ] = m a x 1 < = i < j = n , a [ i ] < a [ j ] ( f [ i ] ) + a [ j ] f[j] = max_{\;1<=i<j=n, a[i] < a[j]}(f[i]) + a[j] f[j]=max1<=i<j=n,a[i]<a[j](f[i])+a[j]

目标状态:
m a x 1 < = i < = n ( f [ i ] ) max_{\;1<=i<=n}(f[i]) max1<=i<=n(f[i])

树状数组优化状态转移:
从求前缀和转求前缀最大值
m a x 1 < = i < j = n , a [ i ] < a [ j ] ( f [ i ] ) = q u e r y ( x − 1 ) , m a p p i n g ( a [ i ] ) = x max_{\;1<=i<j=n, a[i] < a[j]}(f[i]) = query(x-1), \;mapping(a[i]) = x max1<=i<j=n,a[i]<a[j](f[i])=query(x1),mapping(a[i])=x

数组下标表示数值大小 不可以, a [ i ] ∈ [ 1 , 1 0 9 ] a[i]\in[1,10^{9}] a[i][1,109]

离散化:从存储值域转为存储实际存在的值,数的大小关系仍由下标体现,但范围不再离散且那么大,转而连续且取决于数的个数
步骤

  1. 排序 sort(g.begin(), g.end());
  2. 去重 g.erase(unique(g.begin(), g.end()), g.end());
  3. 映射函数mapping(将原始下标映射为离散化存储后的下标) int x = lower_bound(g.begin(), g.end(), a[i]) - g.begin() + 1;

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e5+10;
vector<int> g;
int a[N];
LL tr[N], f[N];
int n, m;
int lowbit(int x)
{return x & -x;
}
void add(int x, LL d)
{for(; x <= m; x += lowbit(x)) tr[x] = max(tr[x], d);
}
LL query(int x)
{LL retval = 0;for(; x; x -= lowbit(x)) retval = max(retval, tr[x]);return retval;
}
int main()
{cin >> n;for(int i = 1; i <= n; i++) cin >> a[i], g.push_back(a[i]);sort(g.begin(), g.end());g.erase(unique(g.begin(), g.end()), g.end());m = g.size();for(int i = 1; i <= n; i++){int x = lower_bound(g.begin(), g.end(), a[i]) - g.begin() + 1;f[i] = query(x-1) + a[i];add(x, f[i]);}LL res = 0;for(int i = 1; i <= n; i++) res = max(res, f[i]);cout << res;return 0;}

这篇关于【最大上升子序列和】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/1131188

相关文章

C++从序列容器中删除元素的四种方法

《C++从序列容器中删除元素的四种方法》删除元素的方法在序列容器和关联容器之间是非常不同的,在序列容器中,vector和string是最常用的,但这里也会介绍deque和list以供全面了解,尽管在一... 目录一、简介二、移除给定位置的元素三、移除与某个值相等的元素3.1、序列容器vector、deque

最长公共子序列问题的深度分析与Java实现方式

《最长公共子序列问题的深度分析与Java实现方式》本文详细介绍了最长公共子序列(LCS)问题,包括其概念、暴力解法、动态规划解法,并提供了Java代码实现,暴力解法虽然简单,但在大数据处理中效率较低,... 目录最长公共子序列问题概述问题理解与示例分析暴力解法思路与示例代码动态规划解法DP 表的构建与意义动

关于最长递增子序列问题概述

《关于最长递增子序列问题概述》本文详细介绍了最长递增子序列问题的定义及两种优化解法:贪心+二分查找和动态规划+状态压缩,贪心+二分查找时间复杂度为O(nlogn),通过维护一个有序的“尾巴”数组来高效... 一、最长递增子序列问题概述1. 问题定义给定一个整数序列,例如 nums = [10, 9, 2

如何提高Redis服务器的最大打开文件数限制

《如何提高Redis服务器的最大打开文件数限制》文章讨论了如何提高Redis服务器的最大打开文件数限制,以支持高并发服务,本文给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录如何提高Redis服务器的最大打开文件数限制问题诊断解决步骤1. 修改系统级别的限制2. 为Redis进程特别设置限制

uva 10131 最长子序列

题意: 给大象的体重和智商,求体重按从大到小,智商从高到低的最长子序列,并输出路径。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vect

poj 3723 kruscal,反边取最大生成树。

题意: 需要征募女兵N人,男兵M人。 每征募一个人需要花费10000美元,但是如果已经招募的人中有一些关系亲密的人,那么可以少花一些钱。 给出若干的男女之间的1~9999之间的亲密关系度,征募某个人的费用是10000 - (已经征募的人中和自己的亲密度的最大值)。 要求通过适当的招募顺序使得征募所有人的费用最小。 解析: 先设想无向图,在征募某个人a时,如果使用了a和b之间的关系

poj 3258 二分最小值最大

题意: 有一些石头排成一条线,第一个和最后一个不能去掉。 其余的共可以去掉m块,要使去掉后石头间距的最小值最大。 解析: 二分石头,最小值最大。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <c

poj 2175 最小费用最大流TLE

题意: 一条街上有n个大楼,坐标为xi,yi,bi个人在里面工作。 然后防空洞的坐标为pj,qj,可以容纳cj个人。 从大楼i中的人到防空洞j去避难所需的时间为 abs(xi - pi) + (yi - qi) + 1。 现在设计了一个避难计划,指定从大楼i到防空洞j避难的人数 eij。 判断如果按照原计划进行,所有人避难所用的时间总和是不是最小的。 若是,输出“OPETIMAL",若

poj 2135 有流量限制的最小费用最大流

题意: 农场里有n块地,其中约翰的家在1号地,二n号地有个很大的仓库。 农场有M条道路(双向),道路i连接着ai号地和bi号地,长度为ci。 约翰希望按照从家里出发,经过若干块地后到达仓库,然后再返回家中的顺序带朋友参观。 如果要求往返不能经过同一条路两次,求参观路线总长度的最小值。 解析: 如果只考虑去或者回的情况,问题只不过是无向图中两点之间的最短路问题。 但是现在要去要回

poj 2594 二分图最大独立集

题意: 求一张图的最大独立集,这题不同的地方在于,间接相邻的点也可以有一条边,所以用floyd来把间接相邻的边也连起来。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <sta