codeforces 16e 状压dp

题意:有n条鱼,他们相遇时会吃掉对方,给出他们相遇时双方获胜的概率,求这n条鱼最后剩下自己的概率。

题解:dp[s]表示当前剩下的鱼的状态为s时的概率。 
那么P(i吃掉j) = P(i和j同时存在) *P(ij相遇)* P(i战胜j) 
即dp[s ^ (1 << j)] += dp[s]  * 1 / (num * (num - 1) / 2) * p[i][j]。num是当前状态下鱼的总数。

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

double dp[1 << 19];
double p[20][20];

int main(){
    int n;
    cin >> n;
    for (int i = 0; i < n; i ++)
        for (int j = 0; j < n; j ++)
            cin >> p[i][j];
    dp[(1 << n) - 1] = 1.0;
    for (int s = (1 << n) - 1; s > 0; s --)
        for (int i = 0; i < n; i ++)
            for (int j = 0; j < n; j ++)
                if ((s & (1 << i)) && (s & (1 << j))){
                    if (i == j) continue;
                    int num = __builtin_popcount(s);
                    dp[s ^ (1 << j)] += dp[s] * p[i][j] / (num * (num - 1) / 2);
                }
    for (int i = 0; i < n; i ++)
        printf("%.6f ", dp[1<<i]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_38759433/article/details/86581204