最近在练习atcoder上的dp场,大概只会做一半.我选出一些不会的题目写一下博客.
题意
按顺序每朵花有一个高度,一个美丽度,选出一个高度上升的子序列,求美丽度之和的最大值.
题解
令
d
p
i
dp_i
dpi表示以第
i
i
i朵花结尾的子序列的美丽度的最大值.
则转移就是找到
i
i
i之前比第
i
i
i朵花矮的位置
d
p
dp
dp的最大值,然后加上第
i
i
i朵花的美丽度.
直接找的话显然是
n
2
n^2
n2的,显然用线段树或者树状数组等数据结构进行维护就可以变成
n
×
l
o
g
(
n
)
n\times log(n)
n×log(n)的了.
代码如下,谢谢大家.
#include<bits/stdc++.h> //Ithea Myse Valgulious
using namespace std;
const int yuzu=2e5;
typedef ll fuko[yuzu|10];
fuko h,a;
struct _bit {
fuko c;
void upt(int x,ll k) {
for (;x<=yuzu;x+=x&-x) c[x]=max(c[x],k);
}
ll query(int x) {
ll zw=0;
for (;x;x-=x&-x) zw=max(zw,c[x]);
return zw;
}
}zw;
int main() {
int n=read(),i;
for (i=1;i<=n;++i) h[i]=read();
for (i=1;i<=n;++i) a[i]=read();
for (i=1;i<=n;++i)
zw.upt(h[i],zw.query(h[i])+a[i]);
printf("%lld\n",zw.query(n));
}