Codeforces 16E Fish 概率DP

这一场好水啊。。这题算是比較简单的概率DP了吧,外加一点状压。

dp[sta] = sigma (dp[sta|(1<<i)]*val[j][i]/( (ans+1)*ans/2 ) ),(i为sta已被吃掉的,j为存活的。ans为存活的个数)。

之所以要除( (ans+1)*ans/2 ),是由于在ans+1条鱼中一共同拥有这些对,且这些对等概率。

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <ctime>
#include <iomanip>

#pragma comment(linker, "/STACK:1024000000");
#define EPS (1e-6)
#define LL long long
#define ULL unsigned long long
#define _LL __int64
#define INF 0x3f3f3f3f
#define Mod 1000000007

/** I/O Accelerator Interface .. **/
#define g (c=getchar())
#define d isdigit(g)
#define p x=x*10+c-'0'
#define n x=x*10+'0'-c
#define pp l/=10,p
#define nn l/=10,n
template<class T> inline T& RD(T &x)
{
    char c;
    while(!d);
    x=c-'0';
    while(d)p;
    return x;
}
template<class T> inline T& RDD(T &x)
{
    char c;
    while(g,c!='-'&&!isdigit(c));
    if (c=='-')
    {
        x='0'-g;
        while(d)n;
    }
    else
    {
        x=c-'0';
        while(d)p;
    }
    return x;
}
inline double& RF(double &x)      //scanf("%lf", &x);
{
    char c;
    while(g,c!='-'&&c!='.'&&!isdigit(c));
    if(c=='-')if(g=='.')
        {
            x=0;
            double l=1;
            while(d)nn;
            x*=l;
        }
        else
        {
            x='0'-c;
            while(d)n;
            if(c=='.')
            {
                double l=1;
                while(d)nn;
                x*=l;
            }
        }
    else if(c=='.')
    {
        x=0;
        double l=1;
        while(d)pp;
        x*=l;
    }
    else
    {
        x=c-'0';
        while(d)p;
        if(c=='.')
        {
            double l=1;
            while(d)pp;
            x*=l;
        }
    }
    return x;
}
#undef nn
#undef pp
#undef n
#undef p
#undef d
#undef g
using namespace std;

double val[20][20];

double dp[1<<18];

bool vis[20];

double dfs(int sta,int n,int ans)
{
    if(dp[sta] > -0.5)
        return dp[sta];

    dp[sta] = 0;

    int i,j;
    double tmp;

    for(i = 0;i < n; ++i)
    {
        if(vis[i] == false)
        {
            vis[i] = true;
            tmp = dfs(sta|(1<<i),n,ans+1);
            vis[i] = false;

            for(j = 0;j < n; ++j)
                if(vis[j])
                    dp[sta] += tmp*val[j][i]/((ans+1)*ans/2.0);
        }
    }

    return dp[sta];
}

int main()
{
    int n,i,j;

    scanf("%d",&n);

    for(i = 0;i < n; ++i)
        for(j = 0;j < n; ++j)
            scanf("%lf",&val[i][j]);

    memset(dp,-1,sizeof(dp));
    dp[(1<<n)-1] = 1;
    memset(vis,false,sizeof(vis));

    for(i = 0;i < n; ++i)
    {
        vis[i] = true;
        dp[1<<i] = dfs(1<<i,n,1);
        vis[i] = false;
    }

    for(i = 0;i < n; ++i)
        printf("%.10lf ",dp[1<<i]);

    return 0;
}









posted @ 2017-05-09 17:45  jzdwajue  阅读(135)  评论(0编辑  收藏  举报