数据结构优化DP

数据结构优化DP

参考题单

Cleaning Shifts S

区间覆盖问题 区间加区间最值线段树维护

cin >> n >> m >> e; m++, e++;

for (int i = 1; i <= n; i++)
	c[i].in();

T.build(1, 1, e);

sort(c + 1, c + 1 + n, [](node a, node b){
	if (a.l == b.l) return a.r < b.r;
	return a.l < b.l;
});

for (int i = 1; i <= n; i++){
	auto [l, r, s] = c[i];
	int t = 0;
	T.update(1, 1, e, l, r, t = T.query(1, 1, e, l - 1) + s);
}

ans = T.query(1, 1, e, e);

cout << ((ans = T.query(1, 1, e, e) == inf ? -1 : ans));

Linear Kingdom Races

同样区间覆盖

cin >> n >> m;

for (int i = 1; i <= n; i++)
	cin >> a[i], s[i] = s[i - 1] + a[i];

for (int i = 1; i <= m; i++)
	b[i].in();

for (int i = 1; i <= m; i++)
	g[b[i].r].push_back({b[i].l, b[i].v});

sort(b + 1, b + 1 + m, [](node a, node b){
	return (a.l == b.l) ? (a.r < b.r) : (a.l < b.l);
});


for (int i = 1; i <= n; i++){
	f[i] = f[i - 1];
	T.update(1, 0, n, 0, i - 1, -a[i]);
	for (auto [l, v] : g[i])
		T.update(1, 0, n, 0, l - 1, v);
	f[i] = max(f[i], T.query(1, 0, n, 0, i - 1));
	T.update(1, 0, n, i, i, f[i]);
}

cout << f[n];

瑰丽华尔兹

按照时间 dp 滚动数组优化一维

void dp(int x, int y, int len, int d, int o){
	int l = 1, r = 0;
	for (int i = 1; in(x, y); x += dx[d], y += dy[d], i++){
		if (mp[x][y] != '.'){ l = 1, r = 0; continue; }
		while(l <= r && q[r].first + i - q[r].second < f[x][y]) r--;
		q[++r] = make_pair(f[x][y], i);
		while(l <= r && q[l].second < i - len) l++;
		f[x][y] = q[l].first + i - q[l].second;
		ans = max(ans, f[x][y]);
	}
}
for (int o = 1, s, t, d, l; o <= k; o++){
	cin >> s >> t >> d; l = t - s + 1;
	if (d == 1) for (int i = 1; i <= m; i++) dp(n, i, l, d, o);
	if (d == 2) for (int i = 1; i <= m; i++) dp(1, i, l, d, o);
	if (d == 3) for (int i = 1; i <= n; i++) dp(i, m, l, d, o);
	if (d == 4) for (int i = 1; i <= n; i++) dp(i, 1, l, d, o);
}

The Battle of Chibi

求长度为 m 的严格上升子序列的个数

O(n2) 转移即可!(离散化)

struct bit{
	int c[N];
	void init() { memset(c, 0, sizeof c); }
	int lb(int x) { return x & (-x); }
	void add(int x, int v){
		for (; x <= n; x += lb(x))
			c[x] += v;
	}
	int find(int x, int res = 0){
		for (; x; x -= lb(x))
			res += c[x];
		return res;
	}
}T[N];
for (int i = 1; i <= n; i++){
	dp[i][1] = 1; T[1].add(a[i], 1);
	for (int k = 2; k <= min(i, m); k++){
		dp[i][k] = T[k - 1].find(a[i] - 1) % mod;
		T[k].add(a[i], dp[i][k]);
	}
}

折线统计

按顺序 dp ,注意当前状态设计, O(n2) 优化为 O(nlogn)

代码难看死了

struct bit{
	int c[N + N];
	int lb(int x) { return x & (-x); }
	void add(int x, int v){
		for (; x <= Y; x += lb(x))
			c[x] += v;
	}
	int find(int x, int res = 0){
		for (; x; x -= lb(x))
			res += c[x];
		return res;
	}
}T[11][2];

for (int i = 1; i <= n; i++){
	f[i][0][1] = f[i][0][0] = 1;
	T[0][0].add(a[i].y, 1);
	T[0][1].add(a[i].y, 1);
	for (int j = 1; j <= m; j++){
		f[i][j][0] = (
			T[j - 1][1].find(Y) 
			+ T[j][0].find(Y) 
			+ mod 
			- (T[j - 1][1].find(a[i].y) + T[j][0].find(a[i].y))
			) % mod;
		f[i][j][1] = (T[j - 1][0].find(a[i].y - 1) + T[j][1].find(a[i].y - 1)) % mod;
		T[j][0].add(a[i].y, f[i][j][0]);
		T[j][1].add(a[i].y, f[i][j][1]);
	}
}

for (int i = 1; i <= n; i++)
	ans += f[i][m][0] + f[i][m][1], ans %= mod;

cout << ans;
posted @   afhuds  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示