题意:数列每个数是在 \([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;
}
标签:return,ARC104E,int,res,Random,len,ans,LIS,mint
From: https://www.cnblogs.com/kevinlikescoding/p/18027070