AGC056B Range Argmax 题解

看数据范围可以大致确定是区间dp。

fl,r 表示只考虑区间 [l,r] 的方案数(只考虑区间 [l,r] 是指只考虑 [li,ri][l,r]xi 方案数)。

转移枚举 [l,r] 中最大的 pi 即可。但是这样会导致一个问题:不同的 p 可能对应相同的 x

我们不妨规定,x 相同的不同 p 排列,只计算最大值出现的那个位置最靠前的一个,最大值出现位置相同的只计算次大值出现的位置最靠前的一个……实际上就是把最大值,次大值,次次大值一直到最小值的出现位置保留字典序最小的那个。

对于转移,假设最大值在 k 位置,[k+1,r] 区间没有影响,但假设 [l,k1] 区间的最大值在 j 位置,如果没有跨过 [j,i] 区间且在 [l,r] 以内的线段(这里的线段指每对 [li,ri])的话,我们可以交换 pi,pj 的值做到更小的字典序。这就给了 [l,k1] 区间的最大值位置一个下限。

因此重新设计状态 fl,r,k 表示只考虑区间 [l,r],最大值位置 k 的方案数。为了转移,令 sl,r,k 表示 [l,r] 区间内,横跨 k 区间的线段中左端点最小的那一个。

fl,r,k=fl,r,k+1+fl,k1,sl,r,kfk+1,r,k+1

总结:这道题告诉我们,在需要对某个序列 a 进行计数时,如果直接计数比较困难但容易对另一个序列 b 进行计数,且多个 b 序列可能对应一个 a 时,可以考虑给 b 加一些限制,常见的如字典序最小。
其实这个思想不一定只在序列上有用,但是应该多数都是在序列上的吧

#include <cstdio>
#include <cstring>

const int mod = 998244353;
int dp[305][305][305], s[305][305][305];
inline int min(const int x, const int y) {return x < y ? x : y;}

int main() {
	int n, m;
	scanf("%d%d", &n, &m);
	memset(s, 0x3f, sizeof s);
	for (int i = 1, l, r; i <= m; ++ i) {
		scanf("%d%d", &l, &r);
		for (int j = l; j <= r; ++ j) s[l][r][j] = min(s[l][r][j], l);
	}
	for (register int i = n; i; -- i)
	for (register int j = i + 1; j <= n; ++ j)
	for (register int k = i; k <= j; ++ k)
		s[i][j][k] = min(j + 1, min(s[i][j][k], min(s[i][j - 1][k], s[i + 1][j][k])));
	for (int i = 1; i <= n; ++ i) dp[i][i][i] = 1;
	for (int i = 1; i <= n + 1; ++ i)
		for (int j = 1; j <= n + 1; ++ j) dp[i][i - 1][j] = 1;
	for (register int l = n; l; -- l)
	for (register int r = l + 1; r <= n; ++ r)
	for (register int k = r; k >= l; -- k)
		dp[l][r][k] = (dp[l][r][k + 1] + 1ll * dp[l][k - 1][s[l][r][k]] * dp[k + 1][r][k + 1]) % mod;
	printf("%d", dp[1][n][1]);
	return 0;
}

本文作者:zqs2020

本文链接:https://www.cnblogs.com/stinger/p/15859464.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   zqs2020  阅读(131)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起
  1. 1 404 not found REOL
404 not found - REOL
00:00 / 00:00
An audio error has occurred.