【Codeforces 678E】【JZOJ 4648】锦标赛

58 篇文章 0 订阅
8 篇文章 0 订阅

Description

403机房最近决定举行一场锦标赛。锦标赛共有N个人参加,共进行N-1轮。第一轮随机挑选两名选手进行决斗,胜者进入下一轮的比赛,第二轮到第N-1轮再每轮随机挑选1名选手与上一轮胜利的选手决斗,最后只剩一轮选手。第i名选手与第j名选手决斗,第i名选手胜利的概率是a[i][j].
作为一号选手的富榄想知道如何安排每轮出场的选手可以使得他获胜的概率最大,并求出这个最大概率。
对于100%的数据,N<=18

Analysis

这题,1.可以从活的推成死的,2.可以从死的推成活的;3.可以从当前推到未来,4.可以从过去推到当前。
但是,这两两组合中,只有从过去推到当前同时从死的推成活的才能满足题意,也即同时满足2&4才能满足题意,为什么呢?
若从活的推到死的,则状态会变成胜负两种,无法统计答案。
反过来呢,最后的状态只有富榄一个人活着,那我们从其他人死的推成活的,合并状态。
所以不能有1
若是2&3,你怎么知道一开始是谁当擂主?又要枚举吗?TLE
所以我们按照2&4的方法DP。

Code

#include<cstdio>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define wengwentao_Orz 1
using namespace std;
typedef double db;
const int N=19;
int n,_2[N];
db a[N][N],f[1<<N][N];
int main()
{
    scanf("%d",&n);
    _2[0]=1;
    fo(i,1,n) _2[i]=_2[i-1]*2;
    fo(i,0,n-1)
        fo(j,0,n-1) scanf("%lf",&a[i][j]);
    f[wengwentao_Orz][0]=1;
    for(int s=3;s<_2[n];s+=2)
        fo(i,0,n-1)
            if(s&_2[i])
                fo(j,0,n-1)
                    if(i!=j && s&_2[j]) f[s][i]=max(f[s][i],f[s^_2[j]][i]*a[i][j]+f[s^_2[i]][j]*a[j][i]);
    db ans=0;
    fo(i,0,n-1) ans=max(ans,f[_2[n]-1][i]);
    printf("%.7lf",ans);
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值