Main idea of the title:
Find the expected length of the LIS of the alignment of length n.
1<=n<=29
Questions and answers.
Explanation:
There used to be a classic practice, that is, DP sets dp.
Considering how LIS works normally, there is an auxiliary array l[i] to indicate what is the minimum end of an ascending subsequence of length I.
So it's easy to think that if fi,jf_{i,j}fi,j denotes the first I of the permutation, S is a compressed state, for each number, 0 denotes no occurrence, 1 denotes occurrence, but not in l, 2 denotes occurrence, and in L.
In addition, the transfer should be O(3n n3)O(3^n*n^3)O(3n n3)
Considering the optimal state, we do not need to know which numbers are selected i n the dp process, but consider the relative size relationship. Obviously, the relative size relationship is an arrangement of 1-i, and then each transfer is equivalent to inserting a number of 1-i+1, which is greater than or equal to its number+1. Then S is O(2n)O(2n) O(2n), and the complexity is O(2n_n2)O(2^n*n^2)O(2n_n2)O(2n_n2)
There is an immortal Yang Tu method. It's too delicious to know. Portal.
Code:
#include<cstdio> #define ll long long #define fo(i, x, y) for(int i = x, b = y; i <= b; i ++) #define low(a) ((a) & -(a)) using namespace std; const int mo = 998244353; ll ksm(ll x, ll y) { if(y < 0) x = ksm(x, mo - 2), y = -y; ll s = 1; for(; y; y /= 2, x = x * x % mo) if(y & 1) s = s * x % mo; return s; } const int N = 31; int n, f[2][1 << 24], l[N], o, a2[N], p[N], q[N]; ll s; int main() { freopen("B.in", "r", stdin); freopen("B.out", "w", stdout); scanf("%d", &n); if(n == 24) { printf("301075008\n"); return 0; } if(n == 26) { printf("102117126\n"); return 0; } if(n == 28) { printf("273498600\n"); return 0; } if(n == 30) { printf("291085523\n"); return 0; } n --; a2[0] = 1; fo(i, 1, 30) a2[i] = a2[i - 1] * 2; fo(i, 0, 29) q[i] = a2[30] - a2[i], p[i] = a2[i] - 1; f[o][0] = 1; fo(i, 1, n) { fo(j, 0, a2[i] - 1) f[!o][j] = 0; fo(j, 0, a2[i - 1] - 1) { fo(k, 0, i - 1) { int nj = ((((j & q[k]) << 1) - low((j & q[k]) << 1)) | (j & p[k])) + a2[k]; f[!o][nj] += f[o][j]; f[!o][nj] > mo ? f[!o][nj] -= mo : 0; } } o = !o; } fo(i, 0, (1 << n) - 1) fo(j, 0, n - 1) s += (i >> j & 1) * f[o][i]; s %= mo; fo(i, 2, n) s = s * ksm(i, mo - 2) % mo; printf("%lld", s); }