P1714 切蛋糕

原题链接

思路

求最大区间和 \(\to\) 设每个点为区间右端点时的最大区间和 \(f[i]\) ,则答案一定为 \(max(f[i])\)
\(\to\) 求最大的 \(f[i]\) \(\to\) 每个 \(f[i]=max(sum[i]-sum[j-1]),j\in[i-k+1,i]\) \(\to\) \(f[i]=sum[i]-min(sum[j-1])\)

所以我们用单调双端队列动态维护
//好抽象啊

code

#include<bits/stdc++.h>
using namespace std;
int pres[500005]={0};
int dp[500005]={0};
struct node
{
    int sum,x;
    bool operator<(const node &b)
    {
        return sum<b.sum;
    }
};
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        int x;
        cin>>x;
        pres[i]=pres[i-1]+x;
    }


    deque<node> q;
    q.push_back({0,0});
    int ans=0;
    for(int i=1;i<=n;i++)
    {
        if(i-q.front().x>m)q.pop_front();
        dp[i]=pres[i]-q.front().sum;
        while(q.size()&&q.back().sum>=pres[i])q.pop_back();
        q.push_back({pres[i],i});
        ans=max(ans,dp[i]);
    }

    cout<<ans;
    return 0;
}

posted @ 2024-03-09 21:52  纯粹的  阅读(21)  评论(0)    收藏  举报