BZOJ 1150: [CTSC2007]数据备份Backup

F[0/1][i][j]表示i不取/取,i和i之前共取了j个的最小距离,wqs二分,最后那个特判0略显有毒

#include<cstdio>
#include<cstring>
using namespace std;
int n,k,s[1000005];
struct node{
	long long val;
	int num;
}F[2][100005];
node check(long long key){
	for (int i=1; i<=n+1; i++) F[0][i]=F[1][i]=(node){1e9,1e9};
	F[0][1]=(node){0,0};
	for (int i=2; i<=n+1; i++){
		if (F[0][i-1].val<F[1][i-1].val || F[0][i-1].val==F[1][i-1].val && F[0][i-1].num<=F[1][i-1].num) F[0][i]=F[0][i-1];
		else F[0][i]=F[1][i-1];
		F[1][i]=(node){F[0][i-1].val+s[i]-s[i-1]-key,F[0][i-1].num+1};
	}
	return F[0][n+1];
}
int main(){
	scanf("%d%d",&n,&k);
	long long L=0,R=0;
	for (int i=1; i<=n; i++){
		scanf("%d",&s[i]);
		R+=s[i];
	}
	while (L<R){
		long long mid=(L+R+1)>>1;
		if (check(mid).num<=k) L=mid;
		else R=mid-1;
	}
	if (check(L).num<=k) printf("%lld\n",F[0][n+1].val+L*k);
	else printf("0\n");
	return 0;
}

  

猜你喜欢

转载自www.cnblogs.com/silenty/p/9786592.html