Loading

【题解】CF559E-Gerald and Path

CF *3000 的题只有紫,可怕。

由于 \(n\) 很小,大概可以确定是个多维 DP。根据套路我们设计 \(f_{i,j}\) 表示前 \(i\) 个区间,最右区间为 \(j\) 的答案。

为了确保转移顺序,我们肯定按端点排序,但是排序后可能还是有问题。

比如 \((-\inf, 0),(1,5),(5,5),(6,\inf)\) 这四个线段,最优解是 \(2\) 号线段向右,\(3\) 号线段向左。但是 \(2\) 号线段向右在 \(3\) 号线段向左的左边,直接转移会出现问题。

所以我们需要一种方式使得直接从 \(1\) 转移到 \(3\)。不难发现从 \(i\) 转移到 \(j(i< j)\),对于所有的 \(k\) 满足 \(i < k < j\),如果 \(k\) 向左,可以被转移 \(i \to k \to j\) 覆盖,所以对所有 \((i,j)\) 中的线段,我们贪心向右一定是最优。

状态 \(\mathcal{O}(N^2)\),枚举后面线段转移,总的时间复杂度 \(\mathcal{O}(N^3)\)

#define N 105
Pr u[N]; int n, ed, f[N][N][2];
int main() {
	u[0].fi = inf_, read(n);
	rp(i, n)read(u[i].fi, u[i].se);
	sort(u + 1, u + n + 1);
	f[0][0][0] = 0;
	rep(i, 0, n)rep(j, 0, i)rep(k, 0, 1){
		cmx(ed, f[i][j][k]); int r = u[j].fi + k * u[j].se;
		int mx = inf_, x = 0, y = 0;
		rep(p, i + 1, n)rep(q, 0, 1){
			int w = u[p].fi + q * u[p].se;
			if(w > r){
				if(w > mx)mx = w, x = p, y = q;
				cmx(f[p][x][y], f[i][j][k] + mx - max(r, w - u[p].se));
			}
		}
	}
	printf("%d\n", ed); return 0;
}

posted @ 2022-05-15 22:10  7KByte  阅读(58)  评论(0编辑  收藏  举报