luogu2627 修剪草坪

设dp[i]表示i位置不选且i之前的都合法的最小损失值。

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
typedef long long ll;
//dp[i] = min{dp[j]} + w[i] | i-j<=k+1 <=> i-k-1<=j<=i-1
int n, k, q[100005], l=1, r;
ll sum, dp[100005], w[100005];
int main(){
	cin>>n>>k;
	for(int i=1; i<=n; i++){
		scanf("%lld", &w[i]);
		sum += w[i];
	}
	for(int i=1; i<=n; i++){
		while(l<=r && q[l]<i-k-1)	l++;
		while(l<=r && dp[q[r]]>dp[i-1])	r--;
		q[++r] = i - 1;
		dp[i] = dp[q[l]] + w[i];
	}
	ll minn=0x3f3f3f3f3f3f3f3f;
	for(int i=n-k; i<=n; i++)
		minn = min(minn, dp[i]);
	cout<<sum-minn<<endl;
	return 0;
}

可参考luogu琪露诺以加强理解

posted @ 2017-12-01 11:15  poorpool  阅读(94)  评论(0编辑  收藏  举报