[ARC104E] Random LIS

题意:数列每个数是在 \([1,a_i]\) 上均匀随机分布的整数,求其最长上升子序列长度的期望,\(n\le 6\)

发现 \(n\) 很小,考虑 \(O(n^n)\) 枚举所有数的偏序关系,然后设 \(h_i=\min_{rk_j=i} a_j\)\(m=\max_{i=1}^n rk_i\)

这样问题就能转化为数列每个数是 \([1_i,h_i]\) 上均匀随机分布的整数,求 \(h_{1\dots m}\) 单调递增的方案数。

\(n\) 很小,直接暴力 \(n^4\) dp,总时间复杂度 \(O(n^{n+4})\)

const int N = 7;
int n, m, a[N], d[N], e[N], h[N], c[N], g[N], len;
mint f[N][N], ans;
mint C(int n, int m) {
	if(n < m || n < 0 || m < 0) return 0;
	mint res = 1;
	FOR(i, 1, m) res *= n - i + 1;
	FOR(i, 1, m) res /= i;
	return res;
}
bool check() {
	FOR(i, 1, n) e[i] = d[i];
	sort(e + 1, e + n + 1);
	FOR(i, 1, n) if(e[i] - e[i - 1] > 1) return 0;
	return 1;
}
int lis() {
	int res = 0;
	FOR(i, 1, n) g[i] = 0;
	FOR(i, 1, n) {
		FOR(j, 0, i - 1) {
			if(d[j] < d[i]) {
				chmax(g[i], g[j] + 1);
			}
		}
		chmax(res, g[i]);
	}
	return res;
}
void calc() {
	FOR(i, 1, n) h[i] = INF; m = 0;
	FOR(i, 1, n) chmin(h[d[i]], a[i]);
	FOR(i, 1, n) chmax(m, d[i]);
	len = 0;
	c[++len] = 0;
	FOR(i, 1, m) c[++len] = h[i];
	sort(c + 1, c + len + 1);
	len = unique(c + 1, c + len + 1) - c - 1;
	FOR(i, 1, m) h[i] = lower_bound(c + 1, c + len + 1, h[i]) - c;
	FOR(i, 0, n) FOR(j, 0, n + 2) f[i][j] = 0;
	f[0][1] = 1;
	FOR(i, 1, m) {
		FOR(j, 2, h[i]) {
			int l = c[j] - c[j - 1];
			ROF(k, i, 1) {
				if(h[k] < j) break;
				FOR(p, 1, j - 1) {
					f[i][j] += C(l, i - k + 1) * f[k - 1][p];
				}
			}
		}
	}
	mint res = 0;
	FOR(i, 2, len) res += f[m][i];
	ans += res * lis();
}
void dfs(int u) {
	if(u == n + 1) {
		if(check()) calc();
		return;
	}
	FOR(i, 1, n) {
		d[u] = i;
		dfs(u + 1);
	}
}
void solve() {
	cin >> n;
	FOR(i, 1, n) cin >> a[i];
	dfs(1);
	FOR(i, 1, n) ans /= a[i];
	cout << ans << endl;
}
posted @ 2024-02-22 12:30  KevinLikesCoding  阅读(12)  评论(0编辑  收藏  举报