_bzoj1010 [HNOI2008]玩具装箱toy【斜率优化dp】

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1010

裸的斜率优化,第一次写队首维护的时候犯了个智障错误,队首维护就是维护队首,我怎么会那队尾两个点的斜率来进行比较。。。

保存斜率优化dp的模版。

#include <cstdio>

const int maxn = 50005;

int n, L, head_, tail;
long long s[maxn], f[maxn];
struct point {
	long long x, y;
	int id;
} que[maxn], t;

inline long long poww(long long aa) {
	return aa * aa;
}
inline long long g(int i) {
	return s[i] + i - L - 1;
}
inline long long h(int i) {
	return s[i] + i;
}
inline double getk(point & aa, point & ss) {
	return (double)(ss.y - aa.y) / (double)(ss.x - aa.x);
}

int main(void) {
	scanf("%d%d", &n, &L);
	for (int i = 1; i <= n; ++i) {
		scanf("%lld", s + i);
		s[i] += s[i - 1];
	}
	que[tail++] = (point){0, 0, 0};
	long long tem;
	int j;
	for (int i = 1; i <= n; ++i) {
		tem = g(i) << 1;
		while (tail - head_ > 1 && getk(que[head_ + 1], que[head_]) <= (double)tem) {
			++head_;
		}
		j = que[head_].id;
		f[i] = f[j] + poww(i - j - 1 + s[i] - s[j] - L);
		t = (point){h(i), f[i] + poww(h(i)), i};
		while (tail - head_ > 1 && getk(t, que[tail - 1]) <= getk(que[tail - 1], que[tail - 2])) {
			--tail;
		}
		que[tail++] = t;
	}
	printf("%lld\n", f[n]);
	return 0;
}

  

posted @ 2016-12-09 14:03  ciao_sora  阅读(171)  评论(0编辑  收藏  举报