题目大意:
是让你在
M
M
M个连续区间中必须选一个,求最小代价总和
思路:
我们可以建一个单调递增队列
q
q
q,
用一个
D
P
DP
DP数组
f
f
f来记录到
i
i
i时的最小代价,那么动态转移方程就是:
f
[
i
]
=
f
[
q
[
h
e
a
d
]
]
+
a
[
i
]
f[i]=f[q[head]]+a[i]
f[i]=f[q[head]]+a[i];
这时我们再用单调队列维护就可
A
C
AC
AC;
代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int a[400010],q[400010];
int ans=214748364;
int f[400010];
int n,m,t=1,h;
int main()
{
cin>>n>>m;
for(int i=1; i<=n; i++)
scanf("%d",&a[i]);
for(int i=1; i<=n; i++)
{
while(h<=t&&f[i-1]<f[q[t]])
t--;
q[++t]=i-1;
while(h<=t&&q[h]<i-m)
h++;
f[i]=f[q[h]]+a[i]; //动态转移
}
for(int i=n-m+1; i<=n; i++) //在最后m个里面找答案。
ans=min(f[i],ans);
cout<<ans;
return 0;
}