●BZOJ 2442 [Usaco2011 Open]修剪草坪

 

题链:

http://www.lydsy.com/JudgeOnline/problem.php?id=2442

题解:

单调队列优化DP
把问题转化为:从序列里选出一些相邻之间间隔不超过K的数,使得和最小,记为ret。
答案即为 SUM-ret
令DP[i]表示要选i位置的数的总代价。
转移 DP[i]=min(DP[i-K-1]~DP[i-1])+A[i],复杂度O(NK)。
然后用单调队列维护转移的最小值就好了。复杂度O(N)。

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#define MAXN 100500
#define ll long long
using namespace std;
ll DP[MAXN],A[MAXN],SUM;
int N,K;
int main(){
	static int pos[MAXN],l,r;
	scanf("%d%d",&N,&K);
	for(int i=1;i<=N;i++) scanf("%lld",&A[i]),SUM+=A[i];
	l=1; r=1; DP[0]=0; pos[l]=0; 
	for(int i=1;i<=N+1;i++){
		while(l<=r&&i-pos[l]>K+1) l++;
		DP[i]=DP[pos[l]]+A[i];
		while(l<=r&&DP[i]<=DP[pos[r]]) r--;
		pos[++r]=i;
	}
	printf("%lld",SUM-DP[N+1]);
	return 0;
}

  

 

posted @ 2018-01-01 21:08  *ZJ  阅读(121)  评论(0编辑  收藏  举报