这个题需要反过来想
f[i] 表示不选i的最小损耗
然后用个单调队列维护一下
#include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<queue> #include<set> #include<map> #include<vector> #include<algorithm> #include<iostream> #define T 110005 using namespace std; int sc() { int i=0; char c=getchar(); while(c>'9'||c<'0')c=getchar(); while(c>='0'&&c<='9')i=i*10+c-'0',c=getchar(); return i; } long long f[T],sum,ans; int a[T],q[T]; int n,k; int main() { n=sc(),k=sc();k++; for(int i=1;i<=n;i++)a[i]=sc(),sum+=a[i]; int l=1,r=1;q[1]=0; for(int i=1;i<=n;i++) { while(l<r&&q[l]+k<i)l++; f[i]=f[q[l]]+a[i]; while(l<=r&&f[i]<=f[q[r]])r--; q[++r]=i; } ans=f[n]; for(int i=n-k+1;i<n;i++)ans=min(ans,f[i]); cout<<sum-ans; return 0; }