●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;
}
Do not go gentle into that good night.
Rage, rage against the dying of the light.
————Dylan Thomas

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号