题目
题目描述
蒜头是一名优秀的画家
蒜头有一张长度为
n
n
n的画卷,在位置
i
i
i上画图案会获得
a
i
a_i
ai的美观度
蒜头是一个有追求的人,因此他希望他的画从左往右是越来越美观的,即对于任意两个画了图案的格子
l
<
r
l < r
l<r,有
a
l
⩽
a
r
a_l \leqslant a_r
al⩽ar
但蒜头发现,人们评判画卷的好坏,并不会只从画出的图案来考虑
具体来说,一张画卷的美观度,定义为所有画了图案的位置的美观度之和与在图上选择两个可以重复的位置使得两位置之间不存在画了图案的位置的方案数之差
现在,蒜头想要知道,他画出的画卷的最大美观度是多少
形式化地,一段连续的长度为
m
m
m的空白位置会让美观度降低
m
(
m
+
1
)
2
\frac{m(m+1)}{2}
2m(m+1)
输入格式
输入的第一行是一个数
n
n
n,表示序列的长度
接下来一行
n
n
n个数,第
i
i
i个数表示
a
i
a_i
ai
输出格式
输出一行表示最大美观度
样例
样例输入
输入样例1
7
1 3 2 7 3 2 4
输入样例2
7
-3 -4 -2 -2 -6 -8 -1
样例输出
输出样例1
7
输出样例2
-11
数据范围与提示
对于
100
%
100 \%
100%的数据,
−
1
0
8
⩽
a
i
⩽
1
0
8
-10^8 \leqslant a_i \leqslant 10^8
−108⩽ai⩽108
对于子任务
1
1
1,
19
19
19分,
n
⩽
20
n \leqslant 20
n⩽20
对于子任务
2
2
2,
22
22
22分,
n
⩽
5000
n \leqslant 5000
n⩽5000
对于子任务
3
3
3,
18
18
18分,
n
⩽
1
0
6
n \leqslant 10^6
n⩽106,数据随机
对于子任务
4
4
4,
41
41
41分,
n
⩽
1
0
6
n \leqslant 10^6
n⩽106
题解
首先,我们先不考虑“对于任意两个画了图案的格子
l
<
r
l<r
l<r,有
a
l
⩽
a
r
a_l \leqslant a_r
al⩽ar”这个条件,正常的进行DP
我们用
f
i
f_i
fi表示只画前
i
i
i个并且一定画第
i
i
i时最大的美观度
我们先写出转移方程:
f
i
=
max
j
<
i
{
f
j
+
a
i
−
(
i
−
j
−
1
)
(
i
−
j
)
2
}
f_i=\max \limits_{j<i}\{f_j+a_i-\frac{(i-j-1)(i-j)}{2}\}
fi=j<imax{fj+ai−2(i−j−1)(i−j)}
我们把
(
i
−
j
−
1
)
(
i
−
j
)
2
\frac{(i-j-1)(i-j)}{2}
2(i−j−1)(i−j)展开,得到:
f
j
+
a
i
−
(
i
−
j
−
1
)
(
i
−
j
)
2
=
f
j
+
a
i
−
i
2
2
−
j
2
2
+
i
j
+
i
2
−
j
2
f_j+a_i-\frac{(i-j-1)(i-j)}{2}=f_j+a_i-\frac{i^2}{2}-\frac{j^2}{2}+ij+\frac{i}{2}-\frac{j}{2}
fj+ai−2(i−j−1)(i−j)=fj+ai−2i2−2j2+ij+2i−2j
接着,我们设
j
<
i
j<i
j<i且
max
k
<
i
{
f
k
+
a
i
−
(
i
−
k
−
1
)
(
i
−
k
)
2
}
=
f
j
+
a
i
−
(
i
−
j
−
1
)
(
i
−
j
)
2
\max \limits_{k<i}\{f_k+a_i-\frac{(i-k-1)(i-k)}{2}\}=f_j+a_i-\frac{(i-j-1)(i-j)}{2}
k<imax{fk+ai−2(i−k−1)(i−k)}=fj+ai−2(i−j−1)(i−j)
那么,我们可以得到
−
f
j
+
j
2
2
+
j
2
=
i
j
−
f
i
+
a
i
−
i
2
2
+
i
2
-f_j+\frac{j^2}{2}+\frac{j}{2}=ij-f_i+a_i-\frac{i^2}{2}+\frac{i}{2}
−fj+2j2+2j=ij−fi+ai−2i2+2i
这样,我们就可以进行斜率优化DP了
解决了DP,我们再从头来考虑一下“对于任意两个画了图案的格子
l
<
r
l<r
l<r,有
a
l
⩽
a
r
a_l \leqslant a_r
al⩽ar”这个条件
这个东西怎么这么熟悉呢?哦!是二维偏序!
所以我们可以使用CDQ分治!
但是排序用什么算法呢?快排吗?
好像太慢了,要
Θ
(
n
l
o
g
2
n
)
\Theta(nlog^2n)
Θ(nlog2n)
如何优化呢?既然是CDQ分治,我们排序就也用分治嘛!我们可以使用归并排序,这样可以预处理出CDQ分治的每一层,节省时间
算了一下,复杂度是
Θ
(
n
l
o
g
n
)
\Theta(nlogn)
Θ(nlogn)
附上代码:
#include<algorithm>
#include<cstdio>
using namespace std;
int n,q[1000010],a[1000010],ord[1000010],rk[21][1000010];
long long ans,f[1000010];
int cmp(const int &x,const int &y)
{
return a[x]<a[y]||(a[x]==a[y]&&x<y);
}
long long Slope(int x)
{
return 2*f[x]-1ll*x*x-x;
}
void Merge_Sort(int l,int r,int d)
{
if(l==r){rk[d][l]=ord[l];return;}
int mid=(l+r)>>1;
Merge_Sort(l,mid,d+1),Merge_Sort(mid+1,r,d+1);
int i=l,j=mid+1,rank=l-1;
while(i<=mid&&j<=r){
if(rk[d+1][i]<rk[d+1][j]) rk[d][++rank]=rk[d+1][i++];
else rk[d][++rank]=rk[d+1][j++];
}
while(i<=mid) rk[d][++rank]=rk[d+1][i++];
while(j<=r) rk[d][++rank]=rk[d+1][j++];
}
void CDQ_DC(int l,int r,int d)
{
if(l==r){
f[ord[l]]=max(f[ord[l]],a[ord[l]]-1ll*(ord[l]-1)*ord[l]/2);
ans=max(ans,f[ord[l]]-1ll*(n-ord[l])*(n-ord[l]+1)/2);
return;
}
int mid=(l+r)>>1,H=1,T=0;
CDQ_DC(l,mid,d+1),q[H]=q[T]=0;
for(int i=mid+1,k=l;i<=r;i++){
int j=rk[d][i];
while(k<=mid&&rk[d][k]<j){
long long w=rk[d][k];
while(H<T&&((Slope(w)-Slope(q[T]))*(q[T]-q[T-1])>=(Slope(q[T])-Slope(q[T-1]))*(w-q[T]))) T--;
q[++T]=w,k++;
}
while(H<T&&(Slope(q[H+1])-Slope(q[H])>=-2ll*j*(q[H+1]-q[H]))) H++;
if(H<=T&&H) f[j]=max(f[j],f[q[H]]+a[j]-1ll*(j-q[H]-1)*(j-q[H])/2);
ans=max(ans,f[j]-1ll*(n-j)*(n-j+1)/2);
}
CDQ_DC(mid+1,r,d+1);
}
int main()
{
freopen("paint.in","r",stdin);
freopen("paint.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]),ord[i]=i,f[i]=-1e18;
sort(ord+1,ord+n+1,cmp),ans=-1ll*n*(n+1)/2,Merge_Sort(1,n,0),CDQ_DC(1,n,1),printf("%lld",ans);
}

蒜头是一名画家,他希望画卷上的图案从左到右越来越美观。画卷美观度由图案美观度之和与未画区域方案数之差决定。本题要求计算蒜头能获得的最大美观度。通过动态规划和二维偏序,结合归并排序进行CDQ分治,实现复杂度为Θ(nlogn)的解决方案。
440

被折叠的 条评论
为什么被折叠?



