hdu4921 Map(狀壓統計)

來源:互聯網
上載者:User

標籤:des   style   blog   http   color   io   for   ar   

hdu4921 Map(狀壓統計)

題意:有10條長度不超過1000鏈,鏈上的節點有權值。我們從這些節點中選出一些節點來,若要選節點u,則u的前繼都得被選進去。對於某一種選定的情況,我們能獲得的權值為,選定的節點的權值和,以及一些附加值。附加值的求法為,對於每條鏈的同一深度的點,若選定的點的個數超過1,那麼會得到的附加值為(si*xi/ci),其中si表示該層選中的點的權值和,xi為該層選中的點的個數,ci為該層的總點數。問,對於所有的選擇情況,能得到的權值期望會是多少?

解法:很直觀的一點,期望值=所有情況的權值和/所有的情況數。情況數很好算,所有的鏈長+1求乘積即可(要減去什麼都不選的一種情況)。而所有的情況的權值和,我們這樣算:因為同一層之間的點,選的個數會對該層產生一個影響,所以我們一層一層考慮。總共只有10條鏈,故考慮任何一層上的點,選或者不選的狀態只有2^10種,那麼我們枚舉這2^10個狀態,對於某一個狀態,我們可以暴力算出能得到的點權和以及附加值,但是對於這個狀態,它會出現在很多種選擇情況當中。比如我們有兩條鏈,鏈長都是3,當前考慮的是第二層的10狀態(二進位1表示選,0表示不選),那麼,當鏈1分別取前2個,前3個,鏈2分別取前0個,前1個。這四種都會包含第二層10的狀態,因此,這個狀態會在4種選擇情況中貢獻給權值總和,故而要將求出的點權和+附加值乘上情況數再累加到權值總和當中,每一層都考慮完了之後,問題得解。

代碼:

#include<stdio.h>#include<string.h>#include<algorithm>#include<vector>using namespace std ;int son[11111] ;int chain[10][1111] , a[11111] ;int vis[11111] , du[11111] , len[11] ;double dfs ( int u , int step , int c ) {    chain[c][step] = a[u] ;    if ( son[u] == -1 ) return step + 2 ;    return dfs ( son[u] , step + 1 , c ) ;}int main () {    int n , m ;    int T ;    scanf ( "%d" , &T ) ;    while ( T -- ) {        scanf ( "%d%d" , &n , &m ) ;        memset ( chain , 0 , sizeof ( chain ) ) ;        memset ( du , 0 , sizeof ( du ) ) ;        memset ( son , -1 , sizeof ( son ) ) ;        for ( int i = 0 ; i < n ; i ++ )            scanf ( "%d" , &a[i] ) ;        for ( int i = 1 ; i <= m ; i ++ ) {            int a , b ;            scanf ( "%d%d" , &a , &b ) ;            son[a] = b ;            du[b] ++ ;        }        double sum = 1 , ans = 0 ;        int tot = 0 ;        for ( int i = 0 ; i < n ; i ++ ) {            if ( du[i] == 0 ) {                len[tot] = dfs ( i , 0 , tot ) ;                sum *= len[tot] ;                len[tot] -- ;                tot ++ ;            }        }        sum -= 1 ;   //     printf ( "sum = %f\n" , sum ) ;        for ( int i = 0 ; i < 1000 ; i ++ ) {            for ( int j = 0 ; j < 1 << tot ; j ++ ) {                int flag = 0 ;                double add = 0 , p = 1 , x = 0 , cnt = 0 ;                for ( int k = 0 ; k < tot ; k ++ ) {                    if ( chain[k][i] ) cnt ++ ;                    if ( j & (1<<k) ) {                        if ( chain[k][i] == 0 ) {                            flag = 1 ;                            break ;                        }                        add += chain[k][i] ;                        x ++ ;                        p *= len[k] - i ;                    }                    else {                        p *= min ( len[k] + 1 , i + 1 ) ;                    }                }                if ( flag ) continue ;                double fuck = ( add + (x>1?(add*x/cnt):0) ) * p ;        //        printf ( "i = %d , j = %d , fuck = %f\n" , i , j , fuck ) ;        //        printf ( "add = %lf , p = %lf , x = %lf , cnt = %lf\n" , add , p , x , cnt ) ;                ans += fuck ;            }        }        printf ( "%.3f\n" , ans / sum ) ;    }    return 0 ;}


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.