P1714 切蛋糕

纯粹的發表於2024-03-09

原題連結

思路

求最大區間和 \(\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;
}

相關文章