题目
前置芝士
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]对应1到i号元素形成的序列中,包括第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(x−1),mapping(a[i])=x
数组下标表示数值大小 不可以,
a
[
i
]
∈
[
1
,
1
0
9
]
a[i]\in[1,10^{9}]
a[i]∈[1,109]
离散化:从存储值域转为存储实际存在的值,数的大小关系仍由下标体现,但范围不再离散且那么大,转而连续且取决于数的个数
步骤
- 排序 sort(g.begin(), g.end());
- 去重 g.erase(unique(g.begin(), g.end()), g.end());
- 映射函数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;
}