POJ1821 Fence

题目链接

POJ182

题目分析:

\(lyd\)\(0x59\)单调队列优化\(DP\)

代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<ctime>
#include<queue>
#define N (20000 + 5)
#define M (100 + 5)
using namespace std;
inline int read() {
	int cnt = 0, f = 1; char c = getchar();
	while (!isdigit(c)) {if (c == '-') f = -f; c = getchar();}
	while (isdigit(c)) {cnt = (cnt << 3) + (cnt << 1) + (c ^ 48); c = getchar();}
	return cnt * f;
}
int n, m, f[M][N];
int q[N], head, tail, pos[N];
struct node {
	int l, p, s;	
}a[M];
bool cmp(node a, node b) {return a.s < b.s;}
int calc(int i, int k) {
	return f[i - 1][k] - a[i].p * k;
}
int main() {
	n = read(), m = read();
	for (register int i = 1; i <= m; ++i) a[i].l = read(), a[i].p = read(), a[i].s = read();
	sort (a + 1, a + m + 1, cmp);
	for (register int i = 1; i <= m; ++i) {
		head = 1, tail = 0;
		for (register int j = max(0, a[i].s - a[i].l); j <= a[i].s - 1; ++j) {
			while (head <= tail && calc(i, q[tail]) <= calc(i, j)) --tail;
			q[++tail] = j;
		}
		for (register int j = 1; j <= n; ++j) {
			f[i][j] = max(f[i][j - 1], f[i - 1][j]);
			if (j < a[i].s) continue;
			while (head <= tail && q[head] < j - a[i].l) ++head;
			if (head <= tail) f[i][j] = max(f[i][j], calc(i, q[head]) + a[i].p * j);
		}
	}
	printf("%d", f[m][n]);
	return 0;
}
posted @ 2019-11-04 15:39  kma_093  阅读(69)  评论(0编辑  收藏  举报