能力強化!!!--NOI爆零賽
阿新 • • 發佈:2018-12-12
資料範圍 n,m,k<=100
首先我們得知道有一個東西叫MIN-MAX容斥
然後我們可以知道只有一個能力時
f[i]表示對於一個能力強化i次後,不強化到滿級的方案數
那麼dp[i][j]表示對於i個能力,總共強化j次,沒有任何一個能力強化到滿級的方案數
那麼dp[i][j]每次用f來轉移一下,相當於做個揹包,乘上組合數就是新的方案數
然後我們把dp[i][0]-dp[i][i*(k-1)]全部加起來,沒有一個強化到滿級的方案數,就等於強化次數大於i次的方案數
所以我們累加起來就是隻有一個滿級的方案數,再除以總的方案數,就是當前子集期望了
我們要求的是全部滿級的期望步數,那麼就是
複雜度大概是O(n^4)
#include <cstdio> #include <algorithm> using namespace std ; #define LL long long int mod = 998244353 ; int fp ( int x , int k ) { int yl = 1 ; while ( k ) { if ( k % 2 ) yl = 1ll * yl * x % mod ; x = 1ll * x * x % mod ; k = k / 2 ; } return yl ; } int a[105] , f[105][205] , N , M , K ; int p[105] , g[10005] ; int MD ( int x ) { return x >= mod ? x - mod : x ; } int jc[100005] , vjc[100005] ; void init ( ) { jc[0] = vjc[0] = 1 ; for ( int i = 1 ; i <= 100000 ; i++ ) jc[i] = 1ll * jc[i-1] * i % mod ; vjc[100000] = fp ( jc[100000] , mod - 2 ) ; for ( int i = 100000 ; i >= 2 ; i-- ) vjc[i-1] = 1ll * vjc[i] * i % mod ; } int group ( int big , int small ) { return 1ll * jc[big] * vjc[big - small] % mod * vjc[small] % mod ; } int ans = 0 ; int main ( ) { scanf ( "%d%d%d" , &N , &M , &K ) ; for ( int i = 1 ; i <= N ; i++ ) scanf ( "%d" , &a[i] ) ; f[0][0] = 1 ; for ( int i = 0 ; i < K ; i++ ) for ( int k = 0 ; k < K ; k++ ) for ( int j = 1 ; j <= N ; j++ ) f[i+1][k+a[j]] = MD( f[i+1][k+a[j]] + f[i][k] ) ; for ( int i = 0 ; i < K ; i++ ) for ( int k = 0 ; k < K ; k++ ) p[i] = MD ( p[i] + f[i][k] ) ; init ( ) ; int pl = -1 ; for ( int i = 0 ; i < K ; i++ ) g[i] = p[i] ; for ( int i = 1 ; i <= M ; i++ ) { pl *= -1 ; int yl = 0 ; int temp=fp(i*N,mod-2); int another=1; int maxa=i*(K-1); for ( int s = 0 ; s <= maxa ; s++ ) yl =MD ( yl + 1ll * g[s] * another % mod) ,another=1ll*another*temp%mod; ans = MD ( ( ans + 1ll * yl * group ( M , i ) % mod * M % mod * fp ( i , mod - 2 ) * pl ) % mod + mod ) ; for ( int s = ( i + 1 ) * ( K - 1 ) ; s >= 0 ; s-- ) { yl = 0 ; for ( int j = 0 ; j <= s && j < K ; j++ ) yl = ( yl + 1ll * g[s - j] * p[j] % mod * group ( s , j ) ) % mod ; g[s] = yl ; } } printf ( "%d\n" , ans ) ; } /* 1 2 1 1 1 3 2 1 2 2 3 1 2 3 5 5 1 2 4 */