codeforces1197D Yet Another Subarray Problem dp

Posted aya-uchida

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codeforces1197D Yet Another Subarray Problem dp相关的知识,希望对你有一定的参考价值。

网址:http://codeforces.com/problemset/problem/1197/D

题意:

给出长度为$n$的序列和$m$,$k$($n \leq 3e5,m \leq 10,k \leq 1e9$),求$\sum_i=l^ra_i-k \lceil \frac r-l+1m \rceil$的最大值。

题解:

第一眼下去感觉是最大子列和,然后直接WA at t3和t8。感觉没问题,后面想想其实不行,因为减去的区间长度是随着子列的长度变化的,就算记录了选取的区间长度进行在线处理。没有丢掉的一段在减去对应的值之后也可能小于丢掉的。所以这个题只能对每一个数枚举其位置,即$j%m==i?(i \in [0,m-1])$,然后让右端点处(满足$j%m==i$)的值减去一个$k$,构成新序列,在新序列上求最大子列和。求解时一定要在到达右端点时才更新最大值,否则会漏减一个$k$。为什么需要这么做?答案一定是出现在某次枚举的右端点,这样子枚举可以在不需要分类讨论就减去相应个数的k,否则有可能出现区间长度大于一个$m$的区间只减去了一个$k$的错误结果。

AC代码:

#include <bits/stdc++.h>
using namespace std;
long long a[300005],b[300005];
int main()

    int n,m,k;
    cin>>n>>m>>k;
    for(int i=0;i<n;++i)
        cin>>a[i];
    long long maxx=0,ans=0;
    for(int i=0;i<m;++i)//枚举减k的位置
    
        for(int j=0;j<n;++j)
            b[j]=a[j]-(j%m==i?k:0);//对需要减k的地方处理
        maxx=0;
        for(int j=0;j<n;++j)
        
            maxx=max(maxx+b[j],0ll);//求最大子列和
            if(j%m==i)
                ans=max(ans,maxx);//保证了所有的最大子列和都减了相应个数的k
            cout<<maxx<<" ";
        
        cout<<endl;
    
    cout<<ans<<endl;
    return 0;

 

以上是关于codeforces1197D Yet Another Subarray Problem dp的主要内容,如果未能解决你的问题,请参考以下文章

Educational Codeforces Round 88 (Rated for Div. 2) D. Yet Another Yet Another Task

Educational Codeforces Round 88 (Rated for Div. 2) D. Yet Another Yet Another Task

CodeForces - 393E Yet Another Number Sequence

Codeforces 903 G. Yet Another Maxflow Problem

[Codeforces 863D]Yet Another Array Queries Problem

codeforces CF903G Yet Another Maxflow Problem 线段树