Educational Codeforces Round 13 E. Another Sith Tournament 概率dp+状压

题目链接:

题目

E. Another Sith Tournament
time limit per test2.5 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output

问题描述

The rules of Sith Tournament are well known to everyone. n Sith take part in the Tournament. The Tournament starts with the random choice of two Sith who will fight in the first battle. As one of them loses, his place is taken by the next randomly chosen Sith who didn't fight before. Does it need to be said that each battle in the Sith Tournament ends with a death of one of opponents? The Tournament ends when the only Sith remains alive.

Jedi Ivan accidentally appeared in the list of the participants in the Sith Tournament. However, his skills in the Light Side of the Force are so strong so he can influence the choice of participants either who start the Tournament or who take the loser's place after each battle. Of course, he won't miss his chance to take advantage of it. Help him to calculate the probability of his victory.

输入

The first line contains a single integer n (1 ≤ n ≤ 18) — the number of participants of the Sith Tournament.

Each of the next n lines contains n real numbers, which form a matrix pij (0 ≤ pij ≤ 1). Each its element pij is the probability that the i-th participant defeats the j-th in a duel.

The elements on the main diagonal pii are equal to zero. For all different i, j the equality pij + pji = 1 holds. All probabilities are given with no more than six decimal places.

Jedi Ivan is the number 1 in the list of the participants.

输出

Output a real number — the probability that Jedi Ivan will stay alive after the Tournament. Absolute or relative error of the answer must not exceed 10 - 6.

样例

input
3
0.0 0.5 0.8
0.5 0.0 0.4
0.2 0.6 0.0

output
0.680000000000000

题意

n个人,每次两个人决斗,输的退场,赢的继续和下一个人打,你可以决定开始决斗的两人和每局上场和赢的人打的那个人。现在你是第0号,问你赢得比赛的最大概率是多少。也就是说在某一固定的上场顺序下,能赢的概率最大,求这个最大概率。

题解

dp[i][j]表示现在还活着的人是状态i(为1的代表活着),在台上的人是j,0号能赢的最大概率。dp[1][0]=1。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int maxn = 18;

double dp[1 << maxn][maxn];
double p[maxn][maxn];
int n;

int main() {
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            scanf("%lf", &p[i][j]);
        }
    }
    memset(dp, 0, sizeof(dp));
    dp[1][0] = 1;
    for (int i = 0; i < (1 << n); i++) {
        for (int j = 0; j < n; j++) if(i&(1<<j)){
            for (int k = 0; k < n; k++)if (i&(1 << k) && k != j) {
                dp[i][j] = max(dp[i][j], p[j][k] * dp[i ^ (1 << k)][j] + p[k][j] * dp[i ^ (1 << j)][k]);
            }
        }
    }
    double ans = 0;
    for (int i = 0; i < n; i++) {
        ans = max(ans, dp[(1 << n) - 1][i]);
    }
    printf("%.15lf\n", ans);
    return 0;
}

转载于:https://www.cnblogs.com/fenice/p/5623520.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值