Codeforces Round #363 (Div. 1) C. LRU(狀態壓縮dp)

這題在博客左上角放了好久了,一直不會做,看了半天題解,勉強看懂。。
參考:http://blog.csdn.net/squee_spoon/article/details/52040852
看看各個博客的講解,看看代碼,強行理解。。。我的理解寫在註釋裏了。

#include <bits/stdc++.h>
using namespace std;

double dp[1<<20];
double p[22];
double ans[22];
int bit_cnt[1<<20];

int main()
{
    ios::sync_with_stdio(false);
    int n,k;
    cin>>n>>k;
    for(int i=0; i<n; i++)
        cin>>p[i];
    int limit = 1<<(n);

    for(int i=1; i<limit; i++)
        bit_cnt[i] = __builtin_popcount(i);

    dp[0] = 1;
    for(int i=1; i<limit; i++)
    {
        dp[i] = 0;
        double pp = 0;
        for(int j=0; j<n; j++)
        {
            if(i&(1<<j))
            {
                //從沒有這位的狀態轉移到當前狀態
                dp[i] += dp[i^(1<<j)] * p[j];
                pp += p[j];
            }
        }
        //如果當前狀態有k位,就是最終狀態,計算答案
        if(bit_cnt[i] == k )
        {
            for(int j=0; j<n; j++)
            {
                if(i&(1<<j))
                    ans[j] += dp[i];
            }
        }
        //留下只選擇這幾個元素的概率
        dp[i] /= (1-pp);
    }

    int cnt = n;
    for(int i=0; i<n; i++)
        if(p[i] == 0)
            cnt--;
    if(cnt<k)
    {
        for(int i=0; i<n; i++)
            cout << fixed << setprecision(8) << ((p[i]==0.0)?0.0:1.0) << " ";
    }
    else
    {
        for(int i=0; i<n; i++)
            cout << fixed << setprecision(8) << ans[i] << " ";
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章