我是靠谱客的博主 潇洒耳机,最近开发中收集的这篇文章主要介绍Codeforces 16E Fish 题解,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

题意简述

n ( < = 18 ) n(<=18) n(<=18)个鱼,其中第 i i i个鱼把第 j j j个与吃掉的概率是 a [ i ] [ j ] a[i][j] a[i][j],保证 a [ i ] [ j ] + a [ j ] [ i ] = 1 , a [ i ] [ i ] = 0 a[i][j]+a[j][i]=1,a[i][i]=0 a[i][j]+a[j][i]=1,a[i][i]=0。会有 n − 1 n-1 n1轮,每一轮会等概率随机选择两个鱼来比♂拼,然后直到最后只剩下一个鱼。对于每个鱼,求最后剩下它的概率。

顺便膜鱼,鱼tql%%%

思路框架

状压 D P DP DP。对于每个状态,枚举已有的鱼,枚举上一次被吃掉的鱼,加一下。

具体思路

d p [ S ] dp[S] dp[S]表示剩下活着的鱼状态为 S S S的概率。那么,我们在 S S S中找到一条鱼 k k k,设它为上一次获胜的。那么上一次死掉的肯定不在 S S S里面了,就到 S S S外面去找一条上一次死掉的鱼 j j j。设 S S S中包含 C C C条鱼,那么 d p [ S ] + = d p [ S   p l u s   j ] × 1 C ( C + 1 ) / 2 × a [ k ] [ j ] dp[S]+=dp[S plus j]times frac{1}{C(C+1)/2} times a[k][j] dp[S]+=dp[S plus j]×C(C+1)/21×a[k][j]。其中 S   p l u s   j S plus j S plus j表示 S S S中加入 j j j,用位运算表示为 [ S ∣ ( 1 ≪ j ) ] [S|(1ll j)] [S(1j)] 1 C ( C + 1 ) / 2 frac{1}{C(C+1)/2} C(C+1)/21 是选择 j j j k k k出来比♂拼的概率, a [ k ] [ j ] a[k][j] a[k][j] k k k j j j吃掉的概率。

然后转移一下。答案就是只选i的状态。

代码:

#include <bits/stdc++.h>
using namespace std;
namespace Flandre_Scarlet
{
    #define N 18
    #define real double
    #define F(i,l,r) for(int i=l;i<=r;++i)
    #define D(i,r,l) for(int i=r;i>=l;--i)
    #define Fs(i,l,r,c) for(int i=l;i<=r;c)
    #define Ds(i,r,l,c) for(int i=r;i>=l;c)
    #define Tra(i,u) for(int i=G.Start(u),__v=G.To(i);~i;i=G.Next(i),__v=G.To(i))
    #define MEM(x,a) memset(x,a,sizeof(x))
    #define FK(x) MEM(x,0)

    int n;
    real a[N][N];
    void Input()
    {
        scanf("%d",&n);
        F(i,0,n-1) F(j,0,n-1) scanf("%lf",&a[i][j]);
    }

    real dp[1<<N];
    void Soviet()
    {
        int All=(1<<n)-1;
        dp[All]=1.00;
        D(i,All-1,0)
        {
            real cnt=(real)__builtin_popcount(i);
            F(j,0,n-1) if (!((1<<j)&i))
            {
                F(k,0,n-1) if ((1<<k)&i)
                {
                    real P=1/(cnt*(cnt+1)/2.00);
                    dp[i]+=dp[i|(1<<j)]*a[k][j]*P;
                }
            }
        }
        F(i,0,n-1)
        {
            printf("%.6f ",dp[(1<<i)]);
        }putchar('n');
    }

    #define Flan void
    Flan IsMyWife()
    {
        Input();
        Soviet();
    }
}
int main()
{
    Flandre_Scarlet::IsMyWife();
    getchar();getchar();
    return 0;
}

最后问一下,那个标题为什么显示不出来啊,有没有人救救我。。。

最后

以上就是潇洒耳机为你收集整理的Codeforces 16E Fish 题解的全部内容,希望文章能够帮你解决Codeforces 16E Fish 题解所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(44)

评论列表共有 0 条评论

立即
投稿
返回
顶部