這題在博客左上角放了好久了,一直不會做,看了半天題解,勉強看懂。。
參考: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;
}