Solution -「AGC 012F」「AT 2366」Prefix Median
阿新 • • 發佈:2020-08-03
\(\mathcal{Description}\)
Link.
給定序列 \(\{a_{2n-1}\}\),將 \(\{a_{2n-1}\}\) 按任意順序排列後,令序列 \(b_i\) 為前 \(2i-1\) 個數的中位數。求 \(\{b_n\}\) 的個數,對 \(10^9+7\) 取模。
\(n\le50\)。
\(\mathcal{Solution}\)
\(\{b_n\}\) 有一個很 naive 的性質:\(b_n\) 是常數,是 \(\{a_{2n-1}\}\) 的中位數。
考慮擴充套件這一性質,從後往前,\(b_{i+1}\) 所對應的 \(a\) 序列刪去兩個數後就得到 \(b_i\)
形式地,有性質:
\[(\forall i\in[1,n))(\not\exists j\in[1,n])(b_i<b_j<b_{i+1}\lor b_{i+1}<b_j<b_i) \]
接著,考慮到中位數本身的性質,將 \(\{a_{2n+1}\}\) 升序排列後,可以確定每個 \(b_i\) 的範圍:
\[a_i\le b_i\le a_{2n-i} \]
那麼設狀態 \(f(i,j,k)\) 表示確定前 \(i\) 位,中位數左邊有 \(j\) 個數可用,右邊有 \(k\)
\(\mathcal{Code}\)
#include <cstdio> #include <algorithm> const int MAXN = 50, MAXM = 100, MOD = 1e9 + 7; int n, m, a[MAXM + 5], f[2][MAXM + 5][MAXM + 5]; inline void addeq ( int& a, const int b ) { if ( ( a += b ) >= MOD ) a -= MOD; } int main () { scanf ( "%d", &n ), m = 2 * n; for ( int i = 1; i < m; ++ i ) scanf ( "%d", &a[i] ); std::sort ( a + 1, a + m ); f[0][0][0] = 1; for ( int i = n, t = 0; i > 1; -- i, t ^= 1 ) { bool dl = a[i] ^ a[i - 1], dr = a[m - i + 1] ^ a[m - i]; for ( int j = 0; j < m; ++ j ) { for ( int k = 0; k < m; ++ k ) { int& cur = f[t][j][k]; if ( ! cur ) continue; addeq ( f[t ^ 1][j + dl][k + dr], cur ); for ( int p = 0; p < j + dl; ++ p ) addeq ( f[t ^ 1][p][k + dr + 1], cur ); for ( int p = 0; p < k + dr; ++ p ) addeq ( f[t ^ 1][j + dl + 1][p], cur ); cur = 0; } } } int ans = 0; for ( int i = 0; i < m; ++ i ) { for ( int j = 0; j < m; ++ j ) { addeq ( ans, f[n & 1 ^ 1][i][j] ); } } printf ( "%d\n", ans ); return 0; }