cf678E. Another Sith Tournament

来源:互联网 发布:沙盘是什么软件 编辑:程序博客网 时间:2024/05/20 03:38

题目大意:有n个选手,给你每个选手战胜另一个选手的概率。赛事为擂台战,选手1很特殊,他可以调换选手的出场顺序,使得自己的胜率最大,求1的胜率。n<=18

题解:如果由初始状态往后递推明显是不行的,因为1可以改变出场顺序状态递推太过困难(选手比赛并不是随机的),我们可以从最终状态开始倒着递推,即确定1必胜,其余状态倒着递推,最后得到都是在1必胜的前提下,dp[I][J](i为擂主,选手状态为j)的概率。

#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>using namespace std;double f[20][1<<18];int n;double p[20][20];int main(){    scanf("%d",&n);    for(int i=0;i<n;i++)    {        for(int j=0;j<n;j++)        {            scanf("%lf",&p[i][j]);        }    }    f[0][1]=1;    double tmp;    for(int i=1;i<(1<<n);i++)    {        for(int j=0;j<n;j++)        {            if(!(i&(1<<j))) continue;            for(int k=0;k<n;k++)            {                if(!(i&(1<<k))) continue;                if(j==k) continue;                double tmp=f[k][i^(1<<j)]*p[k][j]+f[j][i^(1<<k)]*p[j][k];                f[j][i]=max(f[j][i],tmp);            }        }    }    double ans=0;    for(int i=0;i<n;i++)        ans=max(ans,f[i][(1<<n)-1]);    printf("%lf",ans);    return 0;}


0 0
原创粉丝点击