ICode9

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

AGC056B Range Argmax 题解

2022-02-01 19:02:00  阅读:225  来源: 互联网

标签:Argmax 题解 最大值 位置 305 int Range 区间 dp


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

设 \(f_{l,r}\) 表示只考虑区间 \([l,r]\) 的方案数(只考虑区间 \([l,r]\) 是指只考虑 \([l_i,r_i]\in [l,r]\) 的 \(x_i\) 方案数)。

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

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

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

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

\[f_{l,r,k}=f_{l,r,k+1}+f_{l,k-1,s_{l,r,k}}\;f_{k+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;
}

标签:Argmax,题解,最大值,位置,305,int,Range,区间,dp
来源: https://www.cnblogs.com/stinger/p/15859464.html

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

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

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

ICode9版权所有