题意:
FJ有N(1 <= N <= 100,000)只排成一排的奶牛,编号为1…N,
奶牛i的效率为E_i(0 <= E_i <= 1,000,000,000)。
奶牛i的效率为E_i(0 <= E_i <= 1,000,000,000)。
如果FJ安排超过K只连续的奶牛,那么,这些奶牛就会罢工
计算FJ可以得到的最大效率,并且该方案中没有连续的超过K只奶牛。
蒟蒻我的本能反应是两维dp,dp[i][j]表示前i只奶牛,当前连续j只的最大效率
但是发现T飞了,
于是看了题解QAQ,本题的巧妙之处在于考虑损失,用总数减去损失,类似于一些最小割的问题
dp[
i
]
表示
i
不选且之前的选取都合法情况下答案损失的最小值
则dp
[
i
]=min(dp[j])+a
[
i
]
(
i
-j<=k
)
这个可以
用单调队列来维护
单调队列优化
dp
最后是代码
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
int n,h,t,q[200010],k;
long long a[100005],dp[100005],sum,ans;
int main()
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
sum+=a[i];
}
ans=sum;
for(int i=1;i<=n;i++)
{
while(h<t&&q[h]+k+1<i)
h++;
dp[i]=dp[q[h]]+a[i];
while(h<=t&&dp[i]<=dp[q[t]])
t--;
q[++t]=i;
}
for(int i=n-k;i<=n;i++)
ans=min(ans,dp[i]);
printf("%lld\n",sum-ans);
return 0;
}