F-小苯的线性dp
题目链接:https://ac.nowcoder.com/acm/contest/104637/F
题意:
分别对k次操作(0<=k<n)的数组求出其极差的最大值
(每次操作可以合并两个相邻元素)
思路:
显然题目数据范围允许N方做法
发现要让极差变大,只能将最大值变大
因此对于每一个k次操作求得的数组,我们可以枚举钦定一个元素作为其最小值
那么最大值即 其前缀数组 和 后缀数组中 长度范围不超过k+1 的子数组的元素之和
这是本题的关键
每次对ans取max即可
由于默认有前缀 和 后缀,因此当k=n-2时,即数组被划分为了两个区间,此时需要特判
void solve(){
int n;cin>>n;
vector<int>a(n+1);
vector<int>sum(n+1);
for(int i=1;i<=n;i++){
cin>>a[i];sum[i]=sum[i-1]+a[i];
}
for(int k=1;k<=n-2;k++){
vector<int>pre(n+2,0);
vector<int>suf(n+2,0);
for(int i=1;i<=n;i++){
pre[i]=max(pre[i-1],sum[i]-sum[max(0,i-k)]);
}
for(int i=n;i>=1;i--){
suf[i]=max(suf[i+1],sum[min(n,i+k-1)]-sum[i-1]);
}
int ans=0;
for(int i=1;i<=n;i++){
ans=max(ans,max(pre[i-1]-a[i],suf[i+1]-a[i]));
}
cout<<ans<<' ';
}
cout<<max(sum[n]-sum[1]-a[1],sum[n-1]-a[n])<<' '<<0<<endl;
}

浙公网安备 33010602011771号