思路
求最大区间和 \(\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;
}
标签:P1714,int,max,sum,back,蛋糕,ans,pres
From: https://www.cnblogs.com/pure4knowledge/p/18063439