题解:P14242 [CCPC 2024 Shandong I] 分割序列
liuzhongrui · · 题解
思路
首先我们把公式展开来看:
我们把求和顺序调换一下,可以发现每个元素
那么我们要做的事情就是:如何给每个元素分配段编号,使得整体加权和最大。
我们从右往左考虑,当我们从右往左切割时,每多切一刀就会让右边一段的系数增加
于是问题转化成了我们需要知道每个后缀的和,并选择最大的几个后缀加到结果里。
具体而言,我们定义后缀和数组
Code
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=5e5+10;
int n,a[N],suf[N];
signed main(){
int T;cin>>T;
while(T--){
cin>>n;
memset(suf,0,sizeof suf);
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=n;i>=1;i--)suf[i]=suf[i+1]+a[i];
sort(suf+2,suf+n+1,greater<int>());int v=suf[1];
for(int i=1;i<=n;i++)cout<<v<<" ",v+=(i<n)*suf[i+1];
cout<<"\n";
}
return 0;
}