ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CF1146G 题解

2022-04-15 13:02:42  阅读:99  来源: 互联网

标签:le limits read 题解 rep CF1146G max 区间


CF1146G 题解

给一个 DP 的做法。

题意

对长 \(n\) 的序列 \(a\),记 \(f(a)=(\sum\limits_{i=1}^na_i^2)+(\sum\limits_{i=1}^mc_i[\max\limits_{j=l_i}^{r_i}a_j>x_i])\),求 \(\max\limits_{\forall i\in[1,n],a_i\in[0,h]}f(a)\)。

做法

显然需要区间 DP,设 \(f(l,r)\) 代表区间 \([l,r]\) 内的最大收益。

考虑如何处理对区间高度 \(\max\) 的限制,我们可以枚举区间内最小值,来将问题划分成一些子问题。

例如,如果我们想计算 \(f(l,r)\) 的值,我们可以枚举二元组 \((p,z)\),代表 \(\max\limits_{i=l}^ra_i=a_p=z\),

那么对所有满足 \(l\le l_i\le p\le r_i\le r,x_i<z\) 的分区限制 \(i\),\(c_i\) 的罚款是必须要付的,

而对于其他的分区限制是否需要缴纳罚款,还是暂时不能确定的,但我们可以发现,

此时对于区间 \([l,p-1]\) 和 \([p+1,r]\),这两段区间是两个子问题,唯一的限制是最大值 \(a_p=z\) 带来的,

即要求 \(\max\limits_{i=l}^{p-1}a_i\) 和 \(\max\limits_{i=p+1}^ra_i\) 都不超过 \(z\),那么我们可以在 DP 状态中记录 \(z\) 这一维,来处理这个限制。

即,记 \(f(l,r,z)\) 代表区间 \([l,r]\) 内,满足 \(\max\limits_{i=l}^ra_i\le z\) 的最大收益。

此时,区间 \([l,p-1]\) 和 \([p+1,r]\) 内的最大收益,就可以用 \(\max\limits_{x\le z}f(l,p-1,x)\) 和 \(\max\limits_{x\le z}f(p+1,r,x)\) 来表示,

我们维护 DP 数组的前缀最大值,即可做到 \(O(n^4)\) 转移。

code

#include<bits/stdc++.h>
#define ckmax(a, b) ((a) = max((a), (b)))
#define rep(i, a, b) for (int i = (a); i <= (b); i++)
using namespace std;
int read() {/*快读*/}
const int N (55);
int n, m, h, f[N][N][N], lim[N][N][N][N];
struct Node { int l, r, x, c; } q[N];
int dp (int l, int r, int x, int res = -2e9) {
	if (x < 0 || l > r) return 0;
	if (f[l][r][x] != -1) return f[l][r][x];
	rep (p, l, r) ckmax (res, dp (l, p - 1, x) + dp (p + 1, r, x) + x * x + lim[l][r][p][x]);
	return f[l][r][x] = max (res, dp (l, r, x - 1));
}
int main() {
	n = read(), h = read(), m = read();
	rep (i, 1, m) {
		int l = read(), r = read(), x = read(), c = read();
		q[i].l = l, q[i].r = r, q[i].x = x, q[i].c = c;
	}
	rep (l, 1, n) rep (r, l, n) rep (p, l, r) rep (i, 1, m) {
		int L = q[i].l, R = q[i].r, X = q[i].x, C = q[i].c;
		if (l <= L && L <= p && p <= R && R <= r) lim[l][r][p][X + 1] -= C;
	}
	rep (l, 1, n) rep (r, l, n) rep (p, l, r) rep (x, 1, h) lim[l][r][p][x] += lim[l][r][p][x - 1];
	memset (f, -1, sizeof(f)), cout << dp (1, n, h); return 0;
}

标签:le,limits,read,题解,rep,CF1146G,max,区间
来源: https://www.cnblogs.com/GaryH/p/16148549.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有