原題連結
思路
求最大區間和 \(\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;
}